Files
computer-playbook/roles/web-app-mattermost/tasks/02_keycloak.yml

156 lines
8.5 KiB
YAML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
# @see https://docs.mattermost.com/administration-guide/onboard/sso-gitlab.html
- name: "🔍 Resolve keycloak 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: keycloak
resolve_service_name: "{{ lookup('container_service', 'web-app-keycloak', 'keycloak') }}"
resolve_output_prefix: MATTERMOST_KC
resolve_compose_cid: "{{ MATTERMOST_KEYCLOAK_CONTAINER_ADDRESS }}"
resolve_converge_retries: 120
resolve_converge_delay: 5
resolve_cid_filters: "--filter health=healthy"
- name: "🔑 Mattermost | Keycloak — authenticate kcadm.sh"
ansible.builtin.shell: >- # nocheck: container-exec-resolver MATTERMOST_KC_LOCAL_CID resolved at delegate_to runtime; container_address would return a manager-only subshell
container exec -i {{ MATTERMOST_KC_LOCAL_CID | quote }}
/opt/keycloak/bin/kcadm.sh config credentials
--server "http://localhost:8080"
--realm master
--user {{ MATTERMOST_KEYCLOAK_ADMIN_USER | quote }}
--password {{ MATTERMOST_KEYCLOAK_ADMIN_PASS | quote }}
args:
chdir: "{{ lookup('container', 'web-app-keycloak', 'directories.instance') if DEPLOYMENT_MODE == 'compose' else omit }}"
delegate_to: "{{ MATTERMOST_KC_HOST_NODE }}"
changed_when: false
- name: "🔍 Mattermost | Keycloak — resolve Mattermost client UUID"
ansible.builtin.shell: >- # nocheck: container-exec-resolver MATTERMOST_KC_LOCAL_CID resolved at delegate_to runtime; container_address would return a manager-only subshell
container exec -i {{ MATTERMOST_KC_LOCAL_CID | quote }}
/opt/keycloak/bin/kcadm.sh get clients
-r {{ OIDC.CLIENT.REALM | quote }}
-q clientId={{ OIDC.CLIENT.ID | quote }}
--fields id --format csv --noquotes
args:
chdir: "{{ lookup('container', 'web-app-keycloak', 'directories.instance') if DEPLOYMENT_MODE == 'compose' else omit }}"
delegate_to: "{{ MATTERMOST_KC_HOST_NODE }}"
register: mm_kc_client_uuid
changed_when: false
failed_when: mm_kc_client_uuid.stdout_lines | last | trim == ''
- name: "📋 Mattermost | Keycloak — list existing protocol mappers"
ansible.builtin.shell: >- # nocheck: container-exec-resolver MATTERMOST_KC_LOCAL_CID resolved at delegate_to runtime; container_address would return a manager-only subshell
container exec -i {{ MATTERMOST_KC_LOCAL_CID | quote }}
/opt/keycloak/bin/kcadm.sh get
clients/{{ mm_kc_client_uuid.stdout_lines | last | trim }}/protocol-mappers/models
-r {{ OIDC.CLIENT.REALM | quote }}
--fields name --format csv --noquotes
args:
chdir: "{{ lookup('container', 'web-app-keycloak', 'directories.instance') if DEPLOYMENT_MODE == 'compose' else omit }}"
delegate_to: "{{ MATTERMOST_KC_HOST_NODE }}"
register: mm_kc_existing_mappers
changed_when: false
- name: "📋 Mattermost | Keycloak — list all client scopes"
ansible.builtin.shell: >- # nocheck: container-exec-resolver MATTERMOST_KC_LOCAL_CID resolved at delegate_to runtime; container_address would return a manager-only subshell
container exec -i {{ MATTERMOST_KC_LOCAL_CID | quote }}
/opt/keycloak/bin/kcadm.sh get client-scopes
-r {{ OIDC.CLIENT.REALM | quote }}
--fields id,name --format csv --noquotes
args:
chdir: "{{ lookup('container', 'web-app-keycloak', 'directories.instance') if DEPLOYMENT_MODE == 'compose' else omit }}"
delegate_to: "{{ MATTERMOST_KC_HOST_NODE }}"
register: mm_kc_all_scopes
changed_when: false
- name: "📁 Mattermost | Keycloak — create 'openid' client scope if missing"
ansible.builtin.shell: >- # nocheck: container-exec-resolver MATTERMOST_KC_LOCAL_CID resolved at delegate_to runtime; container_address would return a manager-only subshell
container exec -i {{ MATTERMOST_KC_LOCAL_CID | quote }}
/opt/keycloak/bin/kcadm.sh create client-scopes
-r {{ OIDC.CLIENT.REALM | quote }}
-s name=openid
-s protocol=openid-connect
args:
chdir: "{{ lookup('container', 'web-app-keycloak', 'directories.instance') if DEPLOYMENT_MODE == 'compose' else omit }}"
delegate_to: "{{ MATTERMOST_KC_HOST_NODE }}"
when: "mm_kc_all_scopes.stdout_lines | select('search', ',openid$') | list | length == 0"
register: mm_kc_create_openid_scope
- name: "📖 Mattermost | Keycloak — re-read client scopes after possible creation"
ansible.builtin.shell: >- # nocheck: container-exec-resolver MATTERMOST_KC_LOCAL_CID resolved at delegate_to runtime; container_address would return a manager-only subshell
container exec -i {{ MATTERMOST_KC_LOCAL_CID | quote }}
/opt/keycloak/bin/kcadm.sh get client-scopes
-r {{ OIDC.CLIENT.REALM | quote }}
--fields id,name --format csv --noquotes
args:
chdir: "{{ lookup('container', 'web-app-keycloak', 'directories.instance') if DEPLOYMENT_MODE == 'compose' else omit }}"
delegate_to: "{{ MATTERMOST_KC_HOST_NODE }}"
register: mm_kc_all_scopes
changed_when: false
- name: "📋 Mattermost | Keycloak — list existing default client scopes"
ansible.builtin.shell: >- # nocheck: container-exec-resolver MATTERMOST_KC_LOCAL_CID resolved at delegate_to runtime; container_address would return a manager-only subshell
container exec -i {{ MATTERMOST_KC_LOCAL_CID | quote }}
/opt/keycloak/bin/kcadm.sh get
clients/{{ mm_kc_client_uuid.stdout_lines | last | trim }}/default-client-scopes
-r {{ OIDC.CLIENT.REALM | quote }}
--fields name --format csv --noquotes
args:
chdir: "{{ lookup('container', 'web-app-keycloak', 'directories.instance') if DEPLOYMENT_MODE == 'compose' else omit }}"
delegate_to: "{{ MATTERMOST_KC_HOST_NODE }}"
register: mm_kc_default_scopes
changed_when: false
- name: "➕ Mattermost | Keycloak — add 'openid' to client default scopes"
ansible.builtin.shell: >- # nocheck: container-exec-resolver MATTERMOST_KC_LOCAL_CID resolved at delegate_to runtime; container_address would return a manager-only subshell
container exec -i {{ MATTERMOST_KC_LOCAL_CID | quote }}
/opt/keycloak/bin/kcadm.sh update
clients/{{ mm_kc_client_uuid.stdout_lines | last | trim }}/default-client-scopes/{{ mm_kc_all_scopes.stdout_lines | select('search', ',openid$') | first | split(',')
| first | trim }}
-r {{ OIDC.CLIENT.REALM | quote }}
args:
chdir: "{{ lookup('container', 'web-app-keycloak', 'directories.instance') if DEPLOYMENT_MODE == 'compose' else omit }}"
delegate_to: "{{ MATTERMOST_KC_HOST_NODE }}"
when: "'openid' not in mm_kc_default_scopes.stdout"
- name: "➕ Mattermost | Keycloak — add 'id' mapper (integer from LDAP uidNumber)"
ansible.builtin.shell: >- # nocheck: container-exec-resolver MATTERMOST_KC_LOCAL_CID resolved at delegate_to runtime; container_address would return a manager-only subshell
container exec -i {{ MATTERMOST_KC_LOCAL_CID | quote }}
/opt/keycloak/bin/kcadm.sh create
clients/{{ mm_kc_client_uuid.stdout_lines | last | trim }}/protocol-mappers/models
-r {{ OIDC.CLIENT.REALM | quote }}
-s name=mattermost-id
-s protocol=openid-connect
-s protocolMapper=oidc-usermodel-attribute-mapper
-s 'config."user.attribute"=uidNumber'
-s 'config."claim.name"=id'
-s 'config."jsonType.label"=long'
-s 'config."userinfo.token.claim"=true'
-s 'config."id.token.claim"=true'
-s 'config."access.token.claim"=true'
args:
chdir: "{{ lookup('container', 'web-app-keycloak', 'directories.instance') if DEPLOYMENT_MODE == 'compose' else omit }}"
delegate_to: "{{ MATTERMOST_KC_HOST_NODE }}"
when: "'mattermost-id' not in mm_kc_existing_mappers.stdout"
- name: "➕ Mattermost | Keycloak — add 'username' mapper (from Keycloak username)"
ansible.builtin.shell: >- # nocheck: container-exec-resolver MATTERMOST_KC_LOCAL_CID resolved at delegate_to runtime; container_address would return a manager-only subshell
container exec -i {{ MATTERMOST_KC_LOCAL_CID | quote }}
/opt/keycloak/bin/kcadm.sh create
clients/{{ mm_kc_client_uuid.stdout_lines | last | trim }}/protocol-mappers/models
-r {{ OIDC.CLIENT.REALM | quote }}
-s name=mattermost-username
-s protocol=openid-connect
-s protocolMapper=oidc-usermodel-property-mapper
-s 'config."user.attribute"=username'
-s 'config."claim.name"=username'
-s 'config."jsonType.label"=String'
-s 'config."userinfo.token.claim"=true'
-s 'config."id.token.claim"=true'
-s 'config."access.token.claim"=true'
args:
chdir: "{{ lookup('container', 'web-app-keycloak', 'directories.instance') if DEPLOYMENT_MODE == 'compose' else omit }}"
delegate_to: "{{ MATTERMOST_KC_HOST_NODE }}"
when: "'mattermost-username' not in mm_kc_existing_mappers.stdout"