tailscale_rest/models/webhook.rs
1//! Webhook endpoints, and the events they subscribe to.
2
3use crate::Secret;
4use crate::model;
5use crate::models::KnownValues;
6
7/// The destinations whose message format the description knows.
8///
9/// An endpoint with none of these gets Tailscale's own JSON shape, which the
10/// API spells as the empty string rather than by omitting the field.
11pub const PROVIDER_TYPES: &[&str] = &["slack", "mattermost", "googlechat", "discord"];
12
13/// The events a webhook can subscribe to.
14pub const SUBSCRIPTIONS: &[&str] = &[
15 "nodeCreated",
16 "nodeNeedsApproval",
17 "nodeApproved",
18 "nodeKeyExpiringInOneDay",
19 "nodeKeyExpired",
20 "nodeDeleted",
21 "nodeSigned",
22 "nodeNeedsSignature",
23 "policyUpdate",
24 "userCreated",
25 "userNeedsApproval",
26 "userSuspended",
27 "userRestored",
28 "userDeleted",
29 "userApproved",
30 "userRoleUpdated",
31 "subnetIPForwardingNotEnabled",
32 "exitNodeIPForwardingNotEnabled",
33];
34
35/// Four rows for two lists: the description declares `providerType` and
36/// `subscriptions` both inline on `Webhook` and again as schemas of their own,
37/// and the drift test wants every path it walks accounted for.
38pub const KNOWN_VALUES: &[KnownValues] = &[
39 ("Webhook.providerType", PROVIDER_TYPES),
40 ("providerType", PROVIDER_TYPES),
41 ("Webhook.subscriptions[]", SUBSCRIPTIONS),
42 ("subscriptions[]", SUBSCRIPTIONS),
43];
44
45model! {
46 /// An endpoint Tailscale posts events to.
47 Webhook {
48 endpoint_id: "endpointId" => String,
49 /// Where the `POST` goes.
50 endpoint_url: "endpointUrl" => String,
51 /// One of [`PROVIDER_TYPES`], or the empty string for Tailscale's own
52 /// message shape.
53 provider_type: "providerType" => String,
54 /// Blank where the endpoint was created by an OAuth client rather than
55 /// by a person.
56 creator_login_name: "creatorLoginName" => String,
57 created: "created" => String,
58 last_modified: "lastModified" => String,
59 /// Any of [`SUBSCRIPTIONS`].
60 subscriptions: "subscriptions" => Vec<String>,
61 /// Signs the `Tailscale-Webhook-Signature` header, so a receiver can
62 /// tell a real delivery from a forged one. Sent only when the endpoint
63 /// is created and when the secret is rotated.
64 secret: "secret" => Secret,
65 }
66
67 // -----------------------------------------------------------------------
68 // The shapes the routes carry.
69 // -----------------------------------------------------------------------
70
71 /// Every webhook endpoint the tailnet posts to.
72 WebhookList as "GET /tailnet/{tailnet}/webhooks 200" {
73 webhooks: "webhooks" => Vec<Webhook>,
74 }
75
76 /// What creating an endpoint sends.
77 CreateWebhookRequest as "POST /tailnet/{tailnet}/webhooks body" {
78 /// Where the `POST` goes. Required.
79 endpoint_url: "endpointUrl" => String,
80 /// One of [`PROVIDER_TYPES`], which shapes the payload for a receiver
81 /// that expects its own format. Omit for Tailscale's own shape.
82 provider_type: "providerType" => String,
83 /// Which events to send. Any of [`SUBSCRIPTIONS`]. Required.
84 subscriptions: "subscriptions" => Vec<String>,
85 }
86
87 /// What changing one sends, which is the subscriptions and nothing else:
88 /// the URL and the provider cannot be changed after creation.
89 UpdateWebhookRequest as "PATCH /webhooks/{endpointId} body" {
90 subscriptions: "subscriptions" => Vec<String>,
91 }
92}