From 9f970cd69cd1bd5a9b872c8b5c3c0f9eb30e7f05 Mon Sep 17 00:00:00 2001 From: Adrien Touzouli Date: Thu, 2 May 2024 14:04:37 +0200 Subject: [PATCH] fix: make sure Synapse deployment doesn't fail --- .github/workflows/deploy.yml | 2 + README.md | 7 ++ ansible/roles/auth-buttons/tasks/main.yml | 23 ++--- ansible/roles/discovery-rooms/tasks/main.yml | 49 ++++++----- ansible/roles/first-admin/tasks/main.yml | 87 ++++++++++--------- .../roles/synapse-extra-config/tasks/main.yml | 45 +++++----- ansible/roles/synapse/tasks/main.yml | 23 +++-- scripts/ansible_configuration.sh | 7 +- scripts/remove_synapse_deployment.sh | 9 ++ 9 files changed, 147 insertions(+), 105 deletions(-) create mode 100755 scripts/remove_synapse_deployment.sh diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 4b0b8f33..43649a63 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -124,6 +124,8 @@ env: KEYCLOAK_SUBDOMAIN_NAME: ${{ vars.KEYCLOAK_SUBDOMAIN_NAME }} KEYCLOAK_CLIENT_ID: ${{ vars.KEYCLOAK_CLIENT_ID }} KEYCLOAK_CLIENT_SECRET: ${{ secrets.KEYCLOAK_CLIENT_SECRET }} + RESET_SYNAPSE_DEPLOYMENT: ${{ vars.RESET_SYNAPSE_DEPLOYMENT }} + jobs: set_environment: diff --git a/README.md b/README.md index dd813229..e5a1486b 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,13 @@ This will lead to the installation of the following components in the cluster : - a prometheus/grafana stack for monitoring - an alpha unofficial version of a MS teams bridge +## Synapse config update + +There's no easy way to update Synapse configuration (for some good reasons below), so if you made changes to one of the following roles [`first-admin`, `discovery-rooms`, `synapse-extra-config`, `auth-buttons`] you'll need to run the script `./scripts/remove_synapse_deloyment.sh` before running `./scripts/ansible_configuration.sh` script. It's done automatically if env var `RESET_SYNAPSE_DEPLOYMENT` is set to `true`. + +- synapse config lies in configmaps which can't be updated in place +- in extraconfig role, it's possible to disable simple login causing first-admin and auth-buttons to fail. + ## Other credits - [Technology icons created by juicy_fish - Flaticon](https://www.flaticon.com/free-icons/technology) diff --git a/ansible/roles/auth-buttons/tasks/main.yml b/ansible/roles/auth-buttons/tasks/main.yml index 48af877f..6e939f38 100644 --- a/ansible/roles/auth-buttons/tasks/main.yml +++ b/ansible/roles/auth-buttons/tasks/main.yml @@ -3,14 +3,17 @@ # Role used to upload to synapse the images used by authentication buttons # The registered variables mxc_XX contain the MXC uris of the images. They will be used in later roles # -- name: PSC connect button image - upload files to synapse and retrieve the MXC uri - shell: - "curl --data-binary @roles/auth-buttons/files/ProSanteConnect_PICTO_COULEURS.png 'https://{{ matrix.server_name }}/_matrix/media/v3/upload?filename=psc_picto.png' -X 'POST' -H 'Authorization: - Bearer {{ admin_access_token }}' -H 'Content-Type: image/png' --compressed | jq -r '.content_uri'" - register: mxc_psc +- block: + - name: PSC connect button image - upload files to synapse and retrieve the MXC uri + shell: + "curl --data-binary @roles/auth-buttons/files/ProSanteConnect_PICTO_COULEURS.png 'https://{{ matrix.server_name }}/_matrix/media/v3/upload?filename=psc_picto.png' -X 'POST' -H 'Authorization: + Bearer {{ admin_access_token }}' -H 'Content-Type: image/png' --compressed | jq -r '.content_uri'" + register: mxc_psc -- name: EIMIS connect button image - upload files to synapse and retrieve the MXC uri - shell: - "curl --data-binary @roles/auth-buttons/files/eimis-connect.png 'https://{{ matrix.server_name }}/_matrix/media/v3/upload?filename=eimis-connect.png' -X 'POST' -H 'Authorization: - Bearer {{ admin_access_token }}' -H 'Content-Type: image/png' --compressed | jq -r '.content_uri'" - register: mxc_eimis_connect + - name: EIMIS connect button image - upload files to synapse and retrieve the MXC uri + shell: + "curl --data-binary @roles/auth-buttons/files/eimis-connect.png 'https://{{ matrix.server_name }}/_matrix/media/v3/upload?filename=eimis-connect.png' -X 'POST' -H 'Authorization: + Bearer {{ admin_access_token }}' -H 'Content-Type: image/png' --compressed | jq -r '.content_uri'" + register: mxc_eimis_connect + + when: synapse_was_already_running == "0" diff --git a/ansible/roles/discovery-rooms/tasks/main.yml b/ansible/roles/discovery-rooms/tasks/main.yml index db1aabe5..3c8bc045 100644 --- a/ansible/roles/discovery-rooms/tasks/main.yml +++ b/ansible/roles/discovery-rooms/tasks/main.yml @@ -1,27 +1,30 @@ --- -- name: Log in as dummy user to get a token - ansible.builtin.import_tasks: - file: dummy-user.yml +- block: + - name: Log in as dummy user to get a token + ansible.builtin.import_tasks: + file: dummy-user.yml -- name: (re)create the discovery room - ansible.builtin.import_tasks: - file: discovery-room.yml + - name: (re)create the discovery room + ansible.builtin.import_tasks: + file: discovery-room.yml -- name: add all users to discovery room - ansible.builtin.import_tasks: - file: join-discovery-room.yml + - name: add all users to discovery room + ansible.builtin.import_tasks: + file: join-discovery-room.yml -- name: Dummy user joins external discovery rooms listed in matrix.servers_list - uri: - url: "https://{{ matrix.server_name }}/_matrix/client/r0/join/%23discoveryroom:{{ item }}" - method: POST - body: "" - status_code: 200, 201 - body_format: json - use_proxy: false - return_content: no - follow_redirects: all - headers: - Authorization: "Bearer {{ dummy_access_token }}" - loop: "{{ matrix.servers_list }}" - ignore_errors: true + - name: Dummy user joins external discovery rooms listed in matrix.servers_list + uri: + url: "https://{{ matrix.server_name }}/_matrix/client/r0/join/%23discoveryroom:{{ item }}" + method: POST + body: "" + status_code: 200, 201 + body_format: json + use_proxy: false + return_content: no + follow_redirects: all + headers: + Authorization: "Bearer {{ dummy_access_token }}" + loop: "{{ matrix.servers_list }}" + ignore_errors: true + + when: synapse_was_already_running == "0" diff --git a/ansible/roles/first-admin/tasks/main.yml b/ansible/roles/first-admin/tasks/main.yml index 581515b5..abb3e5ac 100644 --- a/ansible/roles/first-admin/tasks/main.yml +++ b/ansible/roles/first-admin/tasks/main.yml @@ -3,51 +3,54 @@ # Role used to create the first admin user # the admin_access_token is registered and user in later roles # -- name: first user creation - retrieve registration_shared_secret - shell: "kubectl get secrets matrix-synapse -o jsonpath=\"{$.data.config\\.yaml}\" | base64 -d | yq -r \".registration_shared_secret\"" - register: registration_shared_secret +- block: + - name: first user creation - retrieve registration_shared_secret + shell: "kubectl get secrets matrix-synapse -o jsonpath=\"{$.data.config\\.yaml}\" | base64 -d | yq -r \".registration_shared_secret\"" + register: registration_shared_secret -- name: first user creation - get a nonce - ansible.builtin.uri: - url: "https://{{ matrix.server_name }}/_synapse/admin/v1/register" - register: nonce + - name: first user creation - get a nonce + ansible.builtin.uri: + url: "https://{{ matrix.server_name }}/_synapse/admin/v1/register" + register: nonce -- name: first user creation - generate hmac - ansible.builtin.shell: | - nonce='{{ nonce.json.nonce }}' - username='{{ matrix.first_eimis_username }}' - password='{{ matrix.first_eimis_password }}' - admin='admin' - secret='{{ registration_shared_secret.stdout }}' - printf '%s\0%s\0%s\0%s' "$nonce" "$username" "$password" "$admin" | - openssl dgst -sha1 -hmac "$secret" | - awk '{print $2}' - register: hmac + - name: first user creation - generate hmac + ansible.builtin.shell: | + nonce='{{ nonce.json.nonce }}' + username='{{ matrix.first_eimis_username }}' + password='{{ matrix.first_eimis_password }}' + admin='admin' + secret='{{ registration_shared_secret.stdout }}' + printf '%s\0%s\0%s\0%s' "$nonce" "$username" "$password" "$admin" | + openssl dgst -sha1 -hmac "$secret" | + awk '{print $2}' + register: hmac -- name: first user creation - try to login and get access-token - ansible.builtin.uri: - url: "https://{{ matrix.server_name }}/_matrix/client/v3/login" - method: POST - body: "{{ lookup('template', 'login.json') }}" - body_format: json - register: login_intent - ignore_errors: true + - name: first user creation - try to login and get access-token + ansible.builtin.uri: + url: "https://{{ matrix.server_name }}/_matrix/client/v3/login" + method: POST + body: "{{ lookup('template', 'login.json') }}" + body_format: json + register: login_intent + ignore_errors: true -- name: first user creation - set access-token var - set_fact: - admin_access_token: "{{ login_intent.json.access_token }}" - when: login_intent.status==200 + - name: first user creation - set access-token var + set_fact: + admin_access_token: "{{ login_intent.json.access_token }}" + when: login_intent.status==200 -- name: first user creation - register user with synapse API and get access-token, only executed if login failed - ansible.builtin.uri: - url: "https://{{ matrix.server_name }}/_synapse/admin/v1/register" - method: POST - body: "{{ lookup('template', 'register.json') }}" - body_format: json - register: register_intent - when: login_intent.status!=200 + - name: first user creation - register user with synapse API and get access-token, only executed if login failed + ansible.builtin.uri: + url: "https://{{ matrix.server_name }}/_synapse/admin/v1/register" + method: POST + body: "{{ lookup('template', 'register.json') }}" + body_format: json + register: register_intent + when: login_intent.status!=200 -- name: first user creation - set admin_access_token var - set_fact: - admin_access_token: "{{ register_intent.json.access_token }}" - when: login_intent.status!=200 + - name: first user creation - set admin_access_token var + set_fact: + admin_access_token: "{{ register_intent.json.access_token }}" + when: login_intent.status!=200 + + when: synapse_was_already_running == "0" diff --git a/ansible/roles/synapse-extra-config/tasks/main.yml b/ansible/roles/synapse-extra-config/tasks/main.yml index d3327968..74960173 100644 --- a/ansible/roles/synapse-extra-config/tasks/main.yml +++ b/ansible/roles/synapse-extra-config/tasks/main.yml @@ -6,27 +6,30 @@ # - the S3 media repo storage # Matrix-synapse pods are restarted at the end of the process # -- name: create extraconfig configmap - kubernetes.core.k8s: - state: present - template: "cm-extraconfig.yml.j2" +- block: + - name: create extraconfig configmap + kubernetes.core.k8s: + state: present + template: "cm-extraconfig.yml.j2" -- name: mount extraconfig configmap on matrix-synapse pod - shell: "kubectl patch deployment matrix-synapse -p '{{ lookup('template', 'deployment-patch.yml') }}' " + - name: mount extraconfig configmap on matrix-synapse pod + shell: "kubectl patch deployment matrix-synapse -p '{{ lookup('template', 'deployment-patch.yml') }}' " -- name: Scale down matrix-synapse deployment - kubernetes.core.k8s_scale: - api_version: v1 - kind: Deployment - name: matrix-synapse - namespace: default - replicas: 0 + - name: Scale down matrix-synapse deployment + kubernetes.core.k8s_scale: + api_version: v1 + kind: Deployment + name: matrix-synapse + namespace: default + replicas: 0 -- name: Scale up matrix-synapse deployment (restart) - kubernetes.core.k8s_scale: - api_version: v1 - kind: Deployment - name: matrix-synapse - namespace: default - replicas: 1 - wait_timeout: 120 + - name: Scale up matrix-synapse deployment (restart) + kubernetes.core.k8s_scale: + api_version: v1 + kind: Deployment + name: matrix-synapse + namespace: default + replicas: 1 + wait_timeout: 120 + + when: synapse_was_already_running == "0" diff --git a/ansible/roles/synapse/tasks/main.yml b/ansible/roles/synapse/tasks/main.yml index e6de61e2..9b548084 100644 --- a/ansible/roles/synapse/tasks/main.yml +++ b/ansible/roles/synapse/tasks/main.yml @@ -8,6 +8,21 @@ name: ananace-charts repo_url: "https://ananace.gitlab.io/charts" +- name: Is synapse already running? + kubernetes.core.k8s_info: + kind: Deployment + name: matrix-synapse + namespace: default + register: synapse_deployment + +- name: Get replicaset number + set_fact: + synapse_was_already_running: "{{ synapse_deployment.resources[0].status.replicas | default(0) }}" + +- name: Display synapse status + debug: + var: synapse_was_already_running + - name: matrix-synapse helm chart kubernetes.core.helm: name: matrix-synapse @@ -18,14 +33,6 @@ values: "{{ lookup('template', 'synapse-chart-config.j2') | from_yaml }}" update_repo_cache: yes -- name: wait for the matrix-synapse replicaset to be ready - shell: 'kubectl get deployments.apps matrix-synapse -o jsonpath="{$.status.conditions}" |jq ''.[] | select(.reason | test("NewReplicaSetAvailable")).message''' - register: rs_message - until: rs_message.stdout.find("successfully") != -1 - retries: 30 - delay: 5 - when: absent_or_present=="present" - - name: Wait for the synapse instance to be up and running ansible.builtin.uri: url: "https://{{ matrix.server_name }}/_matrix/static/" diff --git a/scripts/ansible_configuration.sh b/scripts/ansible_configuration.sh index 3bb1c60f..f390f5e5 100755 --- a/scripts/ansible_configuration.sh +++ b/scripts/ansible_configuration.sh @@ -9,9 +9,14 @@ export WORKING_DIRECTORY=$(pwd) echo "WORKING_DIRECTORY=${WORKING_DIRECTORY}" export ANSIBLE_ROOT="${WORKING_DIRECTORY}/ansible" -export KUBECONFIG="${WORKING_DIRECTORY}/local/kubeconfig.yml" +export KUBECONFIG="${WORKING_DIRECTORY}/local/kubeconfig-${ENVIRONMENT}.yml" echo "KUBECONFIG=${KUBECONFIG}" +if [ "$RESET_SYNAPSE_DEPLOYMENT" = true ]; then + echo "--- remove synapse deployment ---" + "${WORKING_DIRECTORY}/scripts/remove_synapse_deployment.sh" +fi + cd $ANSIBLE_ROOT # Configure ansible diff --git a/scripts/remove_synapse_deployment.sh b/scripts/remove_synapse_deployment.sh new file mode 100755 index 00000000..455c976e --- /dev/null +++ b/scripts/remove_synapse_deployment.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +kubectl delete deployment matrix-synapse matrix-synapse-redis-master matrix-synapse-wellknown-lighttpd + +SECRETS=$(kubectl get secrets | grep matrix-synapse | awk '{print $1}') +kubectl delete secret $SECRETS + +CONFIGMAPS=$(kubectl get cm | grep matrix-synapse | awk '{print $1}') +kubectl delete cm $CONFIGMAPS \ No newline at end of file