--- - name: "🔍 Resolve Zammad railsserver hosting node + container id" ansible.builtin.include_tasks: "{{ lookup('path_absolute', 'roles/sys-svc-compose/tasks/utils/swarm/resolve_host_cid.yml') }}" vars: resolve_service_key: railsserver resolve_service_name: "{{ lookup('container_service', 'web-app-zammad', 'railsserver') }}" resolve_output_prefix: NEXTCLOUD_ZAMMAD resolve_compose_cid: "{{ NEXTCLOUD_ZAMMAD_CONTAINER_ADDRESS }}" resolve_converge_retries: 120 resolve_converge_delay: 5 - name: ⏳ Wait for the Zammad web endpoint wait_for: host: "{{ DOCKER_REACH_HOST }}" port: "{{ lookup('config', 'web-app-zammad', 'services.zammad.ports.local.http') }}" delay: 5 timeout: "{{ lookup('timeout', 600) | int }}" - name: 🔧 Provision the Zammad OAuth application for Nextcloud and capture credentials ansible.builtin.shell: cmd: >- container exec -i -e 'NC_BASE_URL={{ nextcloud_zammad_nc_base_url }}' -e 'NC_REDIRECT_PATH=/apps/integration_zammad/oauth-redirect' -e 'NC_HAS_SECRET={{ nextcloud_zammad_client_secret_current.stdout | trim }}' {{ NEXTCLOUD_ZAMMAD_LOCAL_CID | quote }} bundle exec rails r - stdin: "{{ lookup('file', 'ruby/utils/doorkeeper_allow_onion_redirect.rb') ~ '\n' ~ lookup('file', 'ruby/addons/zammad/provision_oauth_app.rb') }}" delegate_to: "{{ NEXTCLOUD_ZAMMAD_HOST_NODE }}" register: nextcloud_zammad_provision retries: 12 delay: 10 until: nextcloud_zammad_provision.rc == 0 changed_when: "'CLIENT_ID=' in nextcloud_zammad_provision.stdout" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" - name: 🔎 Parse the Zammad OAuth client id set_fact: nextcloud_zammad_client_id: "{{ nextcloud_zammad_provision.stdout | regex_search('CLIENT_ID=(.+)', '\\1') | first }}" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" - name: 🔍 Resolve the Zammad OAuth client secret (freshly emitted or persisted) set_fact: nextcloud_zammad_fresh_secret: "{{ (nextcloud_zammad_provision.stdout | regex_search('CLIENT_SECRET=(.+)', '\\1') | default([], true) | first | default('', true)) | trim }}" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" - name: 🎯 Pick the effective Zammad OAuth client secret set_fact: nextcloud_zammad_client_secret: "{{ nextcloud_zammad_fresh_secret if (nextcloud_zammad_fresh_secret | length > 0) else (nextcloud_zammad_client_secret_current.stdout | trim) }}" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" - name: 🛑 Fail when no usable Zammad OAuth client secret is available assert: that: - (nextcloud_zammad_client_id | default('') | trim) | length > 0 - (nextcloud_zammad_client_secret | default('') | trim) | length > 0 fail_msg: >- Zammad did not return a usable OAuth application. The plaintext client secret is only retrievable when the app is first created or its secret is renewed; reset the integration_zammad client_id/client_secret app config to re-provision. - name: 🔑 Point integration_zammad at the partner instance (admin OAuth instance URL) shell: > {{ NEXTCLOUD_DOCKER_EXEC_OCC }} config:app:set integration_zammad oauth_instance_url --value '{{ nextcloud_zammad_base_url }}' register: nextcloud_zammad_oauth_url_set changed_when: "' set to ' in nextcloud_zammad_oauth_url_set.stdout" - name: 📝 Store integration_zammad OAuth creds Nextcloud-encrypted (sensitive, lazy) ansible.builtin.shell: cmd: >- container exec -i -u {{ NEXTCLOUD_DOCKER_USER }} -e 'NC_APP_ID=integration_zammad' -e 'NC_ENC_MODE=sensitive' -e 'NC_ENC_B64={{ {'client_id': nextcloud_zammad_client_id, 'client_secret': nextcloud_zammad_client_secret} | to_json | b64encode }}' {{ NEXTCLOUD_LOCAL_CID | quote }} php stdin: "{{ lookup('file', 'php/utils/set_encrypted_appconfig.php') }}" register: nextcloud_zammad_enc_set changed_when: "'OK' in nextcloud_zammad_enc_set.stdout" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"