Skip to content

Commit

Permalink
fix: make sure Synapse deployment doesn't fail
Browse files Browse the repository at this point in the history
  • Loading branch information
ad2ien committed Jun 5, 2024
1 parent 6a740c9 commit 9f970cd
Show file tree
Hide file tree
Showing 9 changed files with 147 additions and 105 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
23 changes: 13 additions & 10 deletions ansible/roles/auth-buttons/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
49 changes: 26 additions & 23 deletions ansible/roles/discovery-rooms/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -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"
87 changes: 45 additions & 42 deletions ansible/roles/first-admin/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
45 changes: 24 additions & 21 deletions ansible/roles/synapse-extra-config/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
23 changes: 15 additions & 8 deletions ansible/roles/synapse/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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/"
Expand Down
7 changes: 6 additions & 1 deletion scripts/ansible_configuration.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 9 additions & 0 deletions scripts/remove_synapse_deployment.sh
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 9f970cd

Please sign in to comment.