Matrix provides an "open network for secure, decentralised communication". With Matrix bridges, you can connect to Slack, IRC, Teams, Discord, you name it!
This blog post explains how to interconnect a Tekton pipeline with a Matrix room, for the purpose of notifying the room members of the pipeline status.
Matrix API
Matrix provides several APIs, Client-Server API is one of them.
In order to be able to send messages to a matrix room, the Tekton pipeline needs to send an access_token
along with the request to the Matrix server.
Thus, a prerequisite to this task is to register a Matrix user for the bot with one of the Matrix servers.
Obtaining a Matrix access_token
Once the registration process is done, I obtained the access_token
through a simple login API call:
curl -XPOST -d '{"type":"m.login.password", "user":"sherine.khoury", "password":"take_a_wild_guess"}' "https://matrix.org/_matrix/client/r0/login"
{"user_id":"@sherine.khoury:matrix.org","access_token":"syt_c2hlcmluZS5raG91cnk_NFpzzGCtxFAHEDVKhYTl_123456","home_server":"matrix.org","device_id":"CNYGHLSLQY","well_known":{"m.homeserver":{"base_url":"https://matrix-client.matrix.org/"}}}
With the access_token
, I created a secret, with name matrix-access-token
in the namespace hosting my pipeline, of type generic with a single key, token
, containing the access_token
I just obtained in the step above.
Example
kind: Secret
apiVersion: v1
metadata:
name: matrix-access-token
stringData:
token: {OAuth token for the bot app}
Obtaining the Matrix Room ID
The hardest for me was to create a room with Matrix. I'm pretty new to Matrix 😛, and it seems every server has different rules when it comes to the request body of POST /_matrix/client/v3/createRoom
.
Similarly, every Matrix client calls the room differently: On FluffyChat, it's a Group, which can be created after creating a space. In Element, it's simply called a room!! Thankfully.
When you create a room in Element, the web UI provides the room ID back to you.
But you still need to set a Local address for the room in the Room Settings
in order to be able to query the roomAlias by API. 🤷
The room alias usually is #ROOM_NAME:SERVER_NAME.
So for a room with name my-team on matrix.org, you can also obtain the RoomID by sending the following request to the client-server API:
curl -v https://matrix.org/_matrix/client/v3/directory/room/%23my-room:matrix.org
{"room_id":"!xWldUqOaDUkrHUZRIP:matrix.org","servers":["matrix.org"]}
Notice there is no need for authentication here. Notice also the %23
replacing the #
character in the room alias.
Tekton Task
Largely inspired from the Slack task on TektonHub:
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: send-to-matrix-room
labels:
app.kubernetes.io/version: "0.1"
annotations:
tekton.dev/pipelines.minVersion: "0.12.1"
tekton.dev/categories: Messaging
tekton.dev/tags: messaging
tekton.dev/platforms: "linux/amd64,linux/s390x,linux/ppc64le"
spec:
description: >-
These tasks post a simple message to a matrix room.
This task uses Matrix's Client-Server REST api to send the message.
params:
- name: matrix-access-token
type: string
description: secret name containing matrix access token (key is token)
- name: room
type: string
description: room id (in the format !<ROOM_ID>:<SERVER_NAME>)
- name: endpoint
type: string
description: Matrix server URL to which to send the message
- name: message
type: string
description: plain text message
steps:
- name: post
image: docker.io/curlimages/curl:7.70.0@sha256:031df77a11e5edded840bc761a845eab6e3c2edee22669fb8ad6d59484b6a1c4 #tag: 7.70.0
script: |
#!/bin/sh
/usr/bin/curl -X POST -H 'Content-type: application/json' --data '{"msgtype":"m.text", "body":"$(params.message)"}' https://$(params.endpoint)/_matrix/client/r0/rooms/$(params.room)/send/m.room.message?access_token=$TOKEN
env:
- name: TOKEN
valueFrom:
secretKeyRef:
name: $(params.matrix-access-token)
key: token
💡 It could be an idea to replace
room
andendpoint
by the room alias.
Instead of having a single step I could have used:
- Use
cut -d\: -f2
, I could retrieve the endpoint- Curl the
/_matrix/client/v3/directory/room
to retrieve the RoomID- Send the message using the RoomID and Endpoint
💡 If this looks good, I could send a PR to the TektonHub.
Tekton example pipeline
Now that I've got a task, I can use that task in a pipeline, like so:
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: pipeline-matrix-hello
namespace: okd-team
spec:
params:
- name: matrix-room
description: room id (in the format !<ROOM_ID>:<SERVER_NAME>)
type: string
- name: matrix-endpoint
description: room id (in the format !<ROOM_ID>:<SERVER_NAME>)
type: string
- name: repo-name
description: The repo name
type: string
- name: bundle-version
description: The bundle version
type: string
tasks:
- name: talk-to-matrix
params:
- name: matrix-access-token
value: matrix-access-token
- name: endpoint
value: $(params.matrix-endpoint)
- name: room
value: $(params.matrix-room)
- name: message
value: Going to run operator pipeline on repo $(params.repo-name) to build $(params.bundle-version)
taskRef:
kind: Task
name: send-to-matrix-room
Finally, start the pipeline using
tkn pipeline start pipeline-matrix-hello --param repo-name=node-observability-operator --param bundle-version=v1.1.1 --param matrix-endpoint=matrix.org --param matrix-room=\!yKXXPqFwfCOTipZMxp:matrix.org
The logs of the pipelinerun show:
tkn pipelinerun logs pipeline-matrix-hello-run-hscx9 -f -n okd-team
[talk-to-matrix : post] % Total % Received % Xferd Average Speed Time Time Time Current
[talk-to-matrix : post] Dload Upload Total Spent Left Speed
100 172 0 59 100 113 114 219 --:--:-- --:--:-- --:--:-- 334
[talk-to-matrix : post] {"event_id":"$EYhJ9A5DlMlBx8xD4ORF9q-8r1KmLTsvODvCgwu5xkU"}
Top comments (0)