--- # Exception logic: genuine bidirectional OAuth 2.0 coupling the generic config SPOT cannot do. # integration_suitecrm drives the SuiteCRM OAuth2 password grant and only works once a # "password" client is registered on SuiteCRM; its client_id/client_secret plus the partner # instance URL must then be linked into the connector's admin settings (oauth_instance_url, # client_id, client_secret), none of which the generic config block sets. The client secret is # derived deterministically so provisioning stays idempotent across re-runs on both ends. - name: 🔍 Resolve SuiteCRM partner coupling facts set_fact: nextcloud_crm_container: "{{ lookup('config', 'web-app-suitecrm', 'services.suitecrm.name') }}" nextcloud_crm_instance_dir: "{{ lookup('container', 'web-app-suitecrm', 'directories.instance') }}" nextcloud_crm_base_url: "{{ lookup('tls', 'web-app-suitecrm', 'url.base') | trim }}" nextcloud_crm_client_name: "Nextcloud ({{ lookup('domain', 'web-app-nextcloud') }})" nextcloud_crm_client_secret: "{{ ('integration_suitecrm' ~ lookup('users', 'administrator').password) | hash('sha256') }}" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" - name: 🔍 Probe whether the SuiteCRM partner container is running command: > # nocheck: container-exec-resolver this IS the bare-name partner probe gate, compose co-location container inspect --type container -f '{% raw %}{{.State.Running}}{% endraw %}' {{ nextcloud_crm_container }} register: integration_suitecrm_partner_running changed_when: false failed_when: false - name: 🔧 Provision the bidirectional SuiteCRM <-> Nextcloud OAuth coupling include_tasks: "{{ [role_path, 'tasks/addons/integration_suitecrm_provision.yml'] | path_join }}" when: (integration_suitecrm_partner_running.stdout | trim) == 'true'