Skip to main content

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}