Skip to content

Commit 2706289

Browse files
committed
WIP
Signed-off-by: Danny Kopping <danny@coder.com>
1 parent e65eb03 commit 2706289

File tree

5 files changed

+258
-0
lines changed

5 files changed

+258
-0
lines changed

codersdk/deployment.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2419,6 +2419,7 @@ Write out the current server config as YAML to stdout.`,
24192419
Description: "Password to use with PLAIN/LOGIN authentication.",
24202420
Flag: "notifications-email-auth-password",
24212421
Env: "CODER_NOTIFICATIONS_EMAIL_AUTH_PASSWORD",
2422+
Annotations: serpent.Annotations{}.Mark(annotationSecretKey, "true"),
24222423
Value: &c.Notifications.SMTP.Auth.Password,
24232424
Group: &deploymentGroupNotificationsEmailAuth,
24242425
YAML: "password",

docs/admin/notifications.md

Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
# Notifications
2+
3+
Notifications are sent by Coder in response to specific internal events, such as a workspace being deleted or a user
4+
being created.
5+
6+
**Notifications are currently an experimental feature.**
7+
8+
## Enable experiment
9+
10+
In order to activate the notifications feature, you'll need to enable the `notifications` experiment.
11+
12+
```bash
13+
# Using the CLI flag
14+
$ coder server --experiments=notifications
15+
16+
# Alternatively, using the `CODER_EXPERIMENTS` environment variable
17+
$ CODER_EXPERIMENTS=notifications coder server
18+
```
19+
20+
More information on experiments can be found [here](/docs/contributing/feature-stages#experimental-features).
21+
22+
## Event Types
23+
24+
Notifications are sent in response to internal events, to alert the affected user(s) of this event. Currently we support
25+
the following list of events:
26+
27+
### Workspace Events
28+
29+
_These notifications are sent to the workspace owner._
30+
31+
- Workspace Deleted
32+
- Workspace Manual Build Failure
33+
- Workspace Automatic Build Failure
34+
- Workspace Automatically Updated
35+
- Workspace Dormant
36+
- Workspace Marked For Deletion
37+
38+
### User Events
39+
40+
_These notifications are sent to users with **owner** and **user admin** roles._
41+
42+
- User Account Created
43+
- User Account Deleted
44+
- User Account Suspended
45+
- User Account Activated
46+
- _(coming soon) User Password Reset_
47+
- _(coming soon) User Email Verification_
48+
49+
_These notifications are sent to the user themselves._
50+
51+
- User Account Suspended
52+
- User Account Activated
53+
54+
### Template Events
55+
56+
_These notifications are sent to users with **template admin** roles._
57+
58+
- Template Deleted
59+
60+
## Configuration
61+
62+
| Required | CLI | Env | Type | Description | Default |
63+
|:--------:|-------------------------------------|-----------------------------------------|------------|-----------------------------------------------------------------------------------------------------------------------|---------|
64+
| ✔️ | `--notifications-dispatch-timeout` | `CODER_NOTIFICATIONS_DISPATCH_TIMEOUT` | `duration` | How long to wait while a notification is being sent before giving up. | 1m |
65+
| ✔️ | `--notifications-method` | `CODER_NOTIFICATIONS_METHOD` | `string` | Which delivery method to use (available options: 'smtp', 'webhook'). See [Delivery Methods](#delivery-methods) below. | smtp |
66+
| -️ | `--notifications-max-send-attempts` | `CODER_NOTIFICATIONS_MAX_SEND_ATTEMPTS` | `int` | The upper limit of attempts to send a notification. | 5 |
67+
68+
## Delivery Methods
69+
70+
Notifications can currently be delivery by either SMTP or webhook. Each message can only be delivered to one method, and
71+
this method is configured globally
72+
with [`CODER_NOTIFICATIONS_METHOD`](https://coder.com/docs/reference/cli/server#--notifications-method)
73+
(default: `smtp`).
74+
75+
Enterprise customers can configured which method to use for each of the supported [Events](#events); see
76+
the [Preferences](#preferences)
77+
section below for more details.
78+
79+
## SMTP
80+
81+
Use the `smtp` method to deliver notifications by email to your users. Coder does not ship with an SMTP server, so you
82+
will need to configure Coder to use an existing one.
83+
84+
**Server Settings:**
85+
86+
| Required | CLI | Env | Type | Description | Default |
87+
|:--------:|-----------------------------------|---------------------------------------|-------------|-------------------------------------------|---------------|
88+
| ✔️ | `--notifications-email-from` | `CODER_NOTIFICATIONS_EMAIL_FROM` | `string` | The sender's address to use. | |
89+
| ✔️ | `--notifications-email-smarthost` | `CODER_NOTIFICATIONS_EMAIL_SMARTHOST` | `host:port` | The SMTP relay to send messages through. | localhost:587 |
90+
| -️ | `--notifications-email-hello` | `CODER_NOTIFICATIONS_EMAIL_HELLO` | `string` | The hostname identifying the SMTP server. | localhost |
91+
92+
**Authentication Settings:**
93+
94+
| Required | CLI | Env | Type | Description |
95+
|:--------:|--------------------------------------------|------------------------------------------------|----------|---------------------------------------------------------------------------|
96+
| - | `--notifications-email-auth-username` | `CODER_NOTIFICATIONS_EMAIL_AUTH_USERNAME` | `string` | Username to use with PLAIN/LOGIN authentication. |
97+
| - | `--notifications-email-auth-password` | `CODER_NOTIFICATIONS_EMAIL_AUTH_PASSWORD` | `string` | Password to use with PLAIN/LOGIN authentication. |
98+
| - | `--notifications-email-auth-password-file` | `CODER_NOTIFICATIONS_EMAIL_AUTH_PASSWORD_FILE` | `string` | File from which to load password for use with PLAIN/LOGIN authentication. |
99+
| - | `--notifications-email-auth-identity` | `CODER_NOTIFICATIONS_EMAIL_AUTH_IDENTITY` | `string` | Identity to use with PLAIN authentication. |
100+
101+
**TLS Settings:**
102+
103+
| Required | CLI | Env | Type | Description | Default |
104+
|:--------:|-------------------------------------------|---------------------------------------------|----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|
105+
| - | `--notifications-email-force-tls` | `CODER_NOTIFICATIONS_EMAIL_FORCE_TLS` | `bool` | Force a TLS connection to the configured SMTP smarthost. If port 465 is used, TLS will be forced. See https://datatracker.ietf.org/doc/html/rfc8314#section-3.3. | false |
106+
| - | `--notifications-email-tls-starttls` | `CODER_NOTIFICATIONS_EMAIL_TLS_STARTTLS` | `bool` | Enable STARTTLS to upgrade insecure SMTP connections using TLS. Ignored if `CODER_NOTIFICATIONS_EMAIL_FORCE_TLS` is set. | false |
107+
| - | `--notifications-email-tls-skip-verify` | `CODER_NOTIFICATIONS_EMAIL_TLS_SKIPVERIFY` | `bool` | Skip verification of the target server's certificate (**insecure**). | false |
108+
| - | `--notifications-email-tls-server-name` | `CODER_NOTIFICATIONS_EMAIL_TLS_SERVERNAME` | `string` | Server name to verify against the target certificate. | |
109+
| - | `--notifications-email-tls-cert-file` | `CODER_NOTIFICATIONS_EMAIL_TLS_CERTFILE` | `string` | Certificate file to use. | |
110+
| - | `--notifications-email-tls-cert-key-file` | `CODER_NOTIFICATIONS_EMAIL_TLS_CERTKEYFILE` | `string` | Certificate key file to use. | |
111+
112+
**NOTE:** you _MUST_ use `CODER_NOTIFICATIONS_EMAIL_FORCE_TLS` if your smarthost supports TLS on a port other than `465`.
113+
114+
### Send emails using G-Suite
115+
116+
After setting the required fields above:
117+
118+
1. Create an [App Password](https://myaccount.google.com/apppasswords) using the account you wish to send from
119+
2. Set the following configuration options:
120+
```
121+
CODER_NOTIFICATIONS_EMAIL_SMARTHOST=smtp.gmail.com:465
122+
CODER_NOTIFICATIONS_EMAIL_AUTH_USERNAME=<user>@<domain>
123+
CODER_NOTIFICATIONS_EMAIL_AUTH_PASSWORD="<app password created above>"
124+
```
125+
126+
See [this help article from Google](https://support.google.com/a/answer/176600?hl=en) for more options.
127+
128+
### Send emails using Outlook.com
129+
130+
After setting the required fields above:
131+
132+
1. Setup an account on Microsoft 365 or outlook.com
133+
2. Set the following configuration options:
134+
```
135+
CODER_NOTIFICATIONS_EMAIL_SMARTHOST=smtp-mail.outlook.com:587
136+
CODER_NOTIFICATIONS_EMAIL_TLS_STARTTLS=true
137+
CODER_NOTIFICATIONS_EMAIL_AUTH_USERNAME=<user>@<domain>
138+
CODER_NOTIFICATIONS_EMAIL_AUTH_PASSWORD="<account password>"
139+
```
140+
141+
See [this help article from Microsoft](https://support.microsoft.com/en-us/office/pop-imap-and-smtp-settings-for-outlook-com-d088b986-291d-42b8-9564-9c414e2aa040)
142+
for more options.
143+
144+
## Webhook
145+
146+
The webhook delivery method sends an HTTP POST request to the defined endpoint. The purpose of webhook notifications is
147+
to enable integrations with other systems.
148+
149+
**Settings**:
150+
151+
| Required | CLI | Env | Type | Description |
152+
|:--------:|------------------------------------|----------------------------------------|-------|-----------------------------------------|
153+
| ✔️ | `--notifications-webhook-endpoint` | `CODER_NOTIFICATIONS_WEBHOOK_ENDPOINT` | `url` | The endpoint to which to send webhooks. |
154+
155+
Here is an example payload for Coder's webhook notification:
156+
157+
```json
158+
{
159+
"_version": "1.0",
160+
"msg_id": "88750cad-77d4-4663-8bc0-f46855f5019b",
161+
"payload": {
162+
"_version": "1.0",
163+
"notification_name": "Workspace Deleted",
164+
"user_id": "4ac34fcb-8155-44d5-8301-e3cd46e88b35",
165+
"user_email": "danny@coder.com",
166+
"user_name": "danny",
167+
"user_username": "danny",
168+
"actions": [
169+
{
170+
"label": "View workspaces",
171+
"url": "https://et23ntkhpueak.pit-1.try.coder.app/workspaces"
172+
},
173+
{
174+
"label": "View templates",
175+
"url": "https://et23ntkhpueak.pit-1.try.coder.app/templates"
176+
}
177+
],
178+
"labels": {
179+
"initiator": "danny",
180+
"name": "my-workspace",
181+
"reason": "initiated by user"
182+
}
183+
},
184+
"title": "Workspace \"my-workspace\" deleted",
185+
"body": "Hi danny\n\nYour workspace my-workspace was deleted.\nThe specified reason was \"initiated by user (danny)\"."
186+
}
187+
```
188+
189+
The top-level object has these keys:
190+
191+
- `_version`: describes the version of this schema; follows semantic versioning
192+
- `msg_id`: the UUID of the notification (matches the ID in the `notification_messages` table)
193+
- `payload`: contains the specific details of the notification; described below
194+
- `title`: the title of the notification message (equivalent to a subject in SMTP delivery)
195+
- `body`: the body of the notification message (equivalent to the message body in SMTP delivery)
196+
197+
The `payload` object has these keys:
198+
199+
- `_version`: describes the version of this inner schema; follows semantic versioning
200+
- `notification_name`: name of the event which triggered the notification
201+
- `user_id`: Coder internal user identifier of the target user (UUID)
202+
- `user_email`: email address of the target user
203+
- `user_name`: name of the target user
204+
- `user_username`: username of the target user
205+
- `actions`: a list of CTAs (Call-To-Action); these are mainly relevant for SMTP delivery in which they're shown as
206+
buttons
207+
- `labels`: dynamic map of zero or more string key-value pairs; these vary from event to event
208+
209+
## Preferences (enterprise)
210+
211+
Administrators can configure which delivery methods are used for each different [event type](#event-types).
212+
213+
![preferences](../images/admin/notification-admin-prefs.png)
214+
215+
You can find this page under `https://$CODER_ACCESS_URL/deployment/notifications?tab=events`.
216+
217+
## Stop sending notifications
218+
219+
To pause sending notifications, execute `coder notifications pause`.
220+
221+
To resume sending notifications, execute `coder notifications resume`.
222+
223+
## Internals
224+
225+
The notification system is built to operate concurrently in a single- or multi-replica Coder deployment, and has a
226+
built-in
227+
retry mechanism. It uses the configured Postgres database to store notifications in a queue and facilitate concurrency.
228+
229+
All messages are stored in the `notification_messages` table.
230+
231+
Messages older than 7 days are deleted.
232+
233+
### Message States
234+
235+
![states](../images/admin/notification-states.png)
236+
237+
_A notifier here refers to a Coder replica which is responsible for dispatching the notification. All running replicas
238+
act as notifiers to process pending messages._
239+
240+
- a message begins in `pending` state
241+
- transitions to `leased` when a Coder replica acquires new messages from the database
242+
- new messages are checked for every `CODER_NOTIFICATIONS_FETCH_INTERVAL` (default: 15s)
243+
- if a message is delivered successfully, it transitions to `sent` state
244+
- if a message encounters a non-retryable error (e.g. misconfiguration), it transitions to `permanent_failure`
245+
- if a message encounters a retryable error (e.g. temporary server outage), it transitions to `temporary_failure`
246+
- this message will be retried up to `CODER_NOTIFICATIONS_MAX_SEND_ATTEMPTS` (default: 5)
247+
- this message will transition back to `pending` state after `CODER_NOTIFICATIONS_RETRY_INTERVAL` (default: 5m) and
248+
be retried
249+
- after `CODER_NOTIFICATIONS_MAX_SEND_ATTEMPTS` is exceeded, it transitions to `permanent_failure`
250+
251+
Diagnostic messages will be saved in the `notification_messages` table and will be logged, in the case of failure.
65.8 KB
Loading
35.9 KB
Loading

docs/manifest.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,12 @@
501501
"description": "Learn how to monitor the health of your Coder deployment",
502502
"path": "./admin/healthcheck.md",
503503
"icon_path": "./images/icons/health.svg"
504+
},
505+
{
506+
"title": "Notifications",
507+
"description": "Learn how to configure notifications",
508+
"path": "./admin/notifications.md",
509+
"icon_path": "./images/icons/info.svg"
504510
}
505511
]
506512
},

0 commit comments

Comments
 (0)