mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 10:59:59 +00:00
files/ now mirrors the role's own structure: php, ruby and shell, each split
into addons for the per-integration scripts that tasks/addons/ drives and utils
for what more than one caller shares. set_encrypted_appconfig.php serves gitlab,
mattermost and zammad; doorkeeper_allow_onion_redirect.rb serves zammad and
openproject; init-gate.sh belongs to the role itself. The partner directories
survive because two scripts are both named provision_oauth_app.rb.
NEXTCLOUD_INIT_GATE_FILE had to split. It was the source path under files/, the
name Dockerfile.j2 COPYs into /usr/local/bin, and the ENTRYPOINT, all at once;
moving the script would have produced /usr/local/bin/shell/utils/init-gate.sh.
The basename keeps that name and NEXTCLOUD_INIT_GATE_SRC carries the path.
The same commit closes two of the three faces of one defect. resolve_enabled
reports TLS off for an .onion domain, correctly -- the vhost is plaintext and
Tor carries the transport crypto -- so every redirect URI built from
lookup('tls', ...) is http, and Doorkeeper rejects it. Zammad raises out of
app.save! and fails the task at rc 1; OpenProject discards result.errors, keeps
the unsaved model whose plaintext_secret already exists, reports
oauth_application_created:true, and only dies three tasks later on a null
client_id. The prelude relaxes force_ssl_in_redirect_uri for .onion hosts and
delegates every other host to the previous setting, so clearnet is unchanged at
both partners; the OpenProject script now raises with the real validation
errors.
The third face is PeerTube, whose Keycloak callback is registered http and
requested https, and it stays open: fixing it means changing either PeerTube's
scheme, which is its federation identity, or the registration side.
Evidence: run 31658270172, jobs 94319317307 ("Redirect URI must be an HTTPS/SSL
URI.") and 94319317278 (changed:true, then length on NoneType).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
122 lines
5.7 KiB
YAML
122 lines
5.7 KiB
YAML
---
|
|
- name: "🔍 Resolve Mattermost 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: mattermost
|
|
resolve_service_name: "{{ lookup('container_service', 'web-app-mattermost', 'mattermost') }}"
|
|
resolve_output_prefix: NEXTCLOUD_MM
|
|
resolve_compose_cid: "{{ lookup('container_address', 'web-app-mattermost', 'mattermost') }}"
|
|
resolve_converge_retries: 120
|
|
resolve_converge_delay: 5
|
|
|
|
- name: ⏳ Wait until Mattermost mmctl local mode is ready
|
|
shell: >- # nocheck: container-exec-resolver NEXTCLOUD_MM_LOCAL_CID resolved at delegate_to runtime; container_address would return a manager-only subshell
|
|
container exec -i {{ NEXTCLOUD_MM_LOCAL_CID | quote }}
|
|
/mattermost/bin/mmctl --local system status
|
|
args:
|
|
chdir: "{{ nextcloud_mm_exec_chdir | default(omit) }}"
|
|
delegate_to: "{{ NEXTCLOUD_MM_HOST_NODE }}"
|
|
register: nextcloud_mm_ready
|
|
retries: 60
|
|
delay: 5
|
|
until: nextcloud_mm_ready.rc == 0
|
|
changed_when: false
|
|
failed_when: nextcloud_mm_ready.rc != 0 and nextcloud_mm_ready.attempts | default(0) >= 60
|
|
|
|
- name: 🟢 Enable the Mattermost OAuth 2.0 service provider (required for the connector)
|
|
shell: >- # nocheck: container-exec-resolver NEXTCLOUD_MM_LOCAL_CID resolved at delegate_to runtime; container_address would return a manager-only subshell
|
|
container exec -i {{ NEXTCLOUD_MM_LOCAL_CID | quote }}
|
|
/mattermost/bin/mmctl --local config set ServiceSettings.EnableOAuthServiceProvider true
|
|
args:
|
|
chdir: "{{ nextcloud_mm_exec_chdir | default(omit) }}"
|
|
delegate_to: "{{ NEXTCLOUD_MM_HOST_NODE }}"
|
|
register: nextcloud_mm_oauth_provider
|
|
changed_when: "'true' in nextcloud_mm_oauth_provider.stdout"
|
|
|
|
- name: ⚙️ Generate a short-lived admin personal access token for OAuth provisioning
|
|
shell: >- # nocheck: container-exec-resolver NEXTCLOUD_MM_LOCAL_CID resolved at delegate_to runtime; container_address would return a manager-only subshell
|
|
container exec -i {{ NEXTCLOUD_MM_LOCAL_CID | quote }}
|
|
/mattermost/bin/mmctl --local token generate {{ lookup('users', 'administrator').username }} infinito-nc-oauth-provision --json
|
|
args:
|
|
chdir: "{{ nextcloud_mm_exec_chdir | default(omit) }}"
|
|
delegate_to: "{{ NEXTCLOUD_MM_HOST_NODE }}"
|
|
register: nextcloud_mm_pat
|
|
changed_when: true
|
|
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
|
|
|
|
- name: 🔎 Parse the admin personal access token
|
|
set_fact:
|
|
nextcloud_mm_token: "{{ (nextcloud_mm_pat.stdout | from_json | first).token }}"
|
|
nextcloud_mm_token_id: "{{ (nextcloud_mm_pat.stdout | from_json | first).id }}"
|
|
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
|
|
|
|
- name: "⏳ Wait until the Mattermost HTTP API serves (mmctl local mode skips it)"
|
|
uri_retry:
|
|
url: "{{ nextcloud_mm_local_url }}/api/v4/system/ping"
|
|
timeout: "{{ lookup('timeout', 10) | int }}"
|
|
status_code: 200
|
|
delegate_to: "{{ NEXTCLOUD_MM_HOST_NODE }}"
|
|
register: nextcloud_mm_http_ready
|
|
retries: 30
|
|
delay: 5
|
|
until: nextcloud_mm_http_ready is succeeded
|
|
|
|
- name: 🔧 Provision Mattermost OAuth app for Nextcloud and capture creds (idempotent)
|
|
ansible.builtin.command:
|
|
argv:
|
|
- bash
|
|
- -s
|
|
stdin: "{{ lookup('file', 'shell/addons/mattermost/provision_oauth_app.sh') }}"
|
|
environment:
|
|
MM_LOCAL_URL: "{{ nextcloud_mm_local_url }}"
|
|
MM_TOKEN: "{{ nextcloud_mm_token }}"
|
|
MM_APP_NAME: Nextcloud
|
|
NC_BASE_URL: "{{ NEXTCLOUD_URL }}"
|
|
NC_REDIRECT_PATH: "{{ nextcloud_mm_redirect_path }}"
|
|
MM_HOMEPAGE: "{{ NEXTCLOUD_URL }}"
|
|
delegate_to: "{{ NEXTCLOUD_MM_HOST_NODE }}"
|
|
register: nextcloud_mm_provision
|
|
changed_when: false
|
|
retries: 5
|
|
delay: 5
|
|
until: nextcloud_mm_provision is succeeded
|
|
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
|
|
|
|
- name: 🔎 Parse Mattermost OAuth client credentials
|
|
set_fact:
|
|
nextcloud_mm_client_id: "{{ nextcloud_mm_provision.stdout | regex_search('CLIENT_ID=(.+)', '\\1') | first }}"
|
|
nextcloud_mm_client_secret: "{{ nextcloud_mm_provision.stdout | regex_search('CLIENT_SECRET=(.+)', '\\1') | first }}"
|
|
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
|
|
|
|
- name: 🔧 Point integration_mattermost at partner instance (admin OAuth instance URL)
|
|
shell: >
|
|
{{ NEXTCLOUD_DOCKER_EXEC_OCC }}
|
|
config:app:set integration_mattermost oauth_instance_url
|
|
--value '{{ nextcloud_mm_base_url }}'
|
|
register: nextcloud_mm_oauth_url_set
|
|
changed_when: "' set to ' in nextcloud_mm_oauth_url_set.stdout"
|
|
|
|
# nocheck: container-exec-resolver NEXTCLOUD_LOCAL_CID resolved at delegate_to runtime; container_address would return a manager-only subshell
|
|
- name: 🔐 Store integration_mattermost OAuth credentials Nextcloud-encrypted (lazy)
|
|
ansible.builtin.shell:
|
|
cmd: >-
|
|
container exec -i -u {{ NEXTCLOUD_DOCKER_USER }}
|
|
-e NC_APP_ID=integration_mattermost
|
|
-e NC_ENC_MODE=sensitive
|
|
-e "NC_ENC_B64={{ {'client_id': nextcloud_mm_client_id, 'client_secret': nextcloud_mm_client_secret} | to_json | b64encode }}"
|
|
{{ NEXTCLOUD_LOCAL_CID | quote }} php
|
|
stdin: "{{ lookup('file', 'php/utils/set_encrypted_appconfig.php') }}"
|
|
register: nextcloud_mm_enc_set
|
|
changed_when: "'OK' in nextcloud_mm_enc_set.stdout"
|
|
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
|
|
|
|
- name: 🚫 Revoke the short-lived admin personal access token
|
|
shell: >- # nocheck: container-exec-resolver NEXTCLOUD_MM_LOCAL_CID resolved at delegate_to runtime; container_address would return a manager-only subshell
|
|
container exec -i {{ NEXTCLOUD_MM_LOCAL_CID | quote }}
|
|
/mattermost/bin/mmctl --local token revoke {{ nextcloud_mm_token_id }}
|
|
args:
|
|
chdir: "{{ nextcloud_mm_exec_chdir | default(omit) }}"
|
|
delegate_to: "{{ NEXTCLOUD_MM_HOST_NODE }}"
|
|
changed_when: true
|
|
failed_when: false
|