Skip to content

Commit fbdf4f6

Browse files
committed
Add Vercel Drain resource
1 parent ef1e07e commit fbdf4f6

File tree

10 files changed

+2141
-0
lines changed

10 files changed

+2141
-0
lines changed

client/drain.go

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
package client
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/hashicorp/terraform-plugin-log/tflog"
8+
)
9+
10+
// Drain represents a configurable drain in the Vercel API
11+
type Drain struct {
12+
ID string `json:"id"`
13+
OwnerID string `json:"ownerId"`
14+
Name string `json:"name"`
15+
ProjectIds []string `json:"projectIds"`
16+
Schemas map[string]any `json:"schemas"`
17+
Delivery DeliveryConfig `json:"delivery"`
18+
Sampling []SamplingConfig `json:"sampling,omitempty"`
19+
TeamID string `json:"teamId"`
20+
Status string `json:"status"`
21+
Filter *string `json:"filter,omitempty"`
22+
Transforms []TransformConfig `json:"transforms,omitempty"`
23+
}
24+
25+
// DeliveryConfig represents the delivery configuration for a drain
26+
type DeliveryConfig struct {
27+
Type string `json:"type"`
28+
Endpoint any `json:"endpoint"` // Can be string or object for different delivery types
29+
Encoding string `json:"encoding"`
30+
Compression *string `json:"compression,omitempty"`
31+
Headers map[string]string `json:"headers"`
32+
Secret *string `json:"secret,omitempty"`
33+
}
34+
35+
// SamplingConfig represents sampling configuration for a drain
36+
type SamplingConfig struct {
37+
Type string `json:"type"`
38+
Rate float64 `json:"rate"` // Must be between 0 and 1
39+
Env *string `json:"env,omitempty"`
40+
RequestPath *string `json:"requestPath,omitempty"`
41+
}
42+
43+
// TransformConfig represents transform configuration for a drain
44+
type TransformConfig struct {
45+
ID string `json:"id"`
46+
}
47+
48+
// SchemaConfig represents a schema version configuration
49+
type SchemaConfig struct {
50+
Version string `json:"version"`
51+
}
52+
53+
// CreateDrainRequest represents the request to create a drain
54+
type CreateDrainRequest struct {
55+
TeamID string `json:"-"`
56+
Name string `json:"name"`
57+
Projects string `json:"projects"` // "some" or "all"
58+
ProjectIds []string `json:"projectIds,omitempty"`
59+
Filter *string `json:"filter,omitempty"`
60+
Schemas map[string]SchemaConfig `json:"schemas"`
61+
Delivery DeliveryConfig `json:"delivery"`
62+
Sampling []SamplingConfig `json:"sampling,omitempty"`
63+
Transforms []TransformConfig `json:"transforms,omitempty"`
64+
}
65+
66+
// UpdateDrainRequest represents the request to update a drain
67+
type UpdateDrainRequest struct {
68+
TeamID string `json:"-"`
69+
Name *string `json:"name,omitempty"`
70+
Projects *string `json:"projects,omitempty"`
71+
ProjectIds []string `json:"projectIds,omitempty"`
72+
Filter *string `json:"filter,omitempty"`
73+
Schemas map[string]SchemaConfig `json:"schemas,omitempty"`
74+
Delivery *DeliveryConfig `json:"delivery,omitempty"`
75+
Sampling []SamplingConfig `json:"sampling,omitempty"`
76+
Transforms []TransformConfig `json:"transforms,omitempty"`
77+
Status *string `json:"status,omitempty"` // "enabled" or "disabled"
78+
}
79+
80+
// ListDrainsResponse represents the response from listing drains
81+
type ListDrainsResponse struct {
82+
Drains []Drain `json:"drains"`
83+
}
84+
85+
// CreateDrain creates a new configurable drain
86+
func (c *Client) CreateDrain(ctx context.Context, request CreateDrainRequest) (d Drain, err error) {
87+
url := fmt.Sprintf("%s/v1/drains", c.baseURL)
88+
if c.TeamID(request.TeamID) != "" {
89+
url = fmt.Sprintf("%s?teamId=%s", url, c.TeamID(request.TeamID))
90+
}
91+
payload := string(mustMarshal(request))
92+
tflog.Info(ctx, "creating drain", map[string]any{
93+
"url": url,
94+
"payload": payload,
95+
})
96+
err = c.doRequest(clientRequest{
97+
ctx: ctx,
98+
method: "POST",
99+
url: url,
100+
body: payload,
101+
}, &d)
102+
return d, err
103+
}
104+
105+
// GetDrain retrieves a drain by ID
106+
func (c *Client) GetDrain(ctx context.Context, id, teamID string) (d Drain, err error) {
107+
url := fmt.Sprintf("%s/v1/drains/%s", c.baseURL, id)
108+
if c.TeamID(teamID) != "" {
109+
url = fmt.Sprintf("%s?teamId=%s", url, c.TeamID(teamID))
110+
}
111+
tflog.Info(ctx, "reading drain", map[string]any{
112+
"url": url,
113+
})
114+
err = c.doRequest(clientRequest{
115+
ctx: ctx,
116+
method: "GET",
117+
url: url,
118+
}, &d)
119+
return d, err
120+
}
121+
122+
// UpdateDrain updates an existing drain
123+
func (c *Client) UpdateDrain(ctx context.Context, id string, request UpdateDrainRequest) (d Drain, err error) {
124+
url := fmt.Sprintf("%s/v1/drains/%s", c.baseURL, id)
125+
if c.TeamID(request.TeamID) != "" {
126+
url = fmt.Sprintf("%s?teamId=%s", url, c.TeamID(request.TeamID))
127+
}
128+
payload := string(mustMarshal(request))
129+
tflog.Info(ctx, "updating drain", map[string]any{
130+
"url": url,
131+
"payload": payload,
132+
})
133+
err = c.doRequest(clientRequest{
134+
ctx: ctx,
135+
method: "PATCH",
136+
url: url,
137+
body: payload,
138+
}, &d)
139+
return d, err
140+
}
141+
142+
// DeleteDrain deletes a drain by ID
143+
func (c *Client) DeleteDrain(ctx context.Context, id, teamID string) error {
144+
url := fmt.Sprintf("%s/v1/drains/%s", c.baseURL, id)
145+
if c.TeamID(teamID) != "" {
146+
url = fmt.Sprintf("%s?teamId=%s", url, c.TeamID(teamID))
147+
}
148+
tflog.Info(ctx, "deleting drain", map[string]any{
149+
"url": url,
150+
})
151+
return c.doRequest(clientRequest{
152+
ctx: ctx,
153+
method: "DELETE",
154+
url: url,
155+
}, nil)
156+
}
157+
158+
// ListDrains retrieves all drains for a team
159+
func (c *Client) ListDrains(ctx context.Context, teamID string) (response ListDrainsResponse, err error) {
160+
url := fmt.Sprintf("%s/v1/drains", c.baseURL)
161+
if c.TeamID(teamID) != "" {
162+
url = fmt.Sprintf("%s?teamId=%s", url, c.TeamID(teamID))
163+
}
164+
tflog.Info(ctx, "listing drains", map[string]any{
165+
"url": url,
166+
})
167+
err = c.doRequest(clientRequest{
168+
ctx: ctx,
169+
method: "GET",
170+
url: url,
171+
}, &response)
172+
return response, err
173+
}

docs/data-sources/drain.md

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "vercel_drain Data Source - terraform-provider-vercel"
4+
subcategory: ""
5+
description: |-
6+
Provides information about an existing Drain.
7+
Drains collect various types of data including logs, traces, analytics, and speed insights from your Vercel projects.
8+
This is a more generic version of log drains that supports multiple data types and delivery methods.
9+
Teams on Pro and Enterprise plans can create configurable drains from the Vercel dashboard.
10+
---
11+
12+
# vercel_drain (Data Source)
13+
14+
Provides information about an existing Drain.
15+
16+
Drains collect various types of data including logs, traces, analytics, and speed insights from your Vercel projects.
17+
This is a more generic version of log drains that supports multiple data types and delivery methods.
18+
19+
Teams on Pro and Enterprise plans can create configurable drains from the Vercel dashboard.
20+
21+
## Example Usage
22+
23+
```terraform
24+
# Read information about an existing drain
25+
data "vercel_drain" "example" {
26+
id = "drain_123456789"
27+
}
28+
29+
# Use with team context
30+
data "vercel_drain" "team_drain" {
31+
id = "drain_987654321"
32+
team_id = "team_abc123"
33+
}
34+
35+
# You can then reference the drain's configuration
36+
output "drain_name" {
37+
value = data.vercel_drain.example.name
38+
}
39+
40+
output "drain_status" {
41+
value = data.vercel_drain.example.status
42+
}
43+
44+
output "drain_delivery_type" {
45+
value = data.vercel_drain.example.delivery.type
46+
}
47+
48+
output "drain_schemas" {
49+
value = data.vercel_drain.example.schemas
50+
}
51+
```
52+
53+
<!-- schema generated by tfplugindocs -->
54+
## Schema
55+
56+
### Required
57+
58+
- `id` (String) The ID of the Drain.
59+
60+
### Optional
61+
62+
- `team_id` (String) The ID of the team the Drain should exist under. Required when configuring a team resource if a default team has not been set in the provider.
63+
64+
### Read-Only
65+
66+
- `delivery` (Attributes) Configuration for how data should be delivered. (see [below for nested schema](#nestedatt--delivery))
67+
- `filter` (String) A filter expression applied to incoming data.
68+
- `name` (String) The name of the Drain.
69+
- `project_ids` (Set of String) A list of project IDs that the drain should be associated with.
70+
- `projects` (String) Whether to include all projects or a specific set. Valid values are `all` or `some`.
71+
- `sampling` (Attributes Set) Sampling configuration for the drain. (see [below for nested schema](#nestedatt--sampling))
72+
- `schemas` (Map of Object) A map of schema configurations. Keys can be `log`, `trace`, `analytics`, or `speed_insights`. (see [below for nested schema](#nestedatt--schemas))
73+
- `status` (String) The status of the drain.
74+
- `transforms` (Attributes Set) Transform configurations for the drain. (see [below for nested schema](#nestedatt--transforms))
75+
76+
<a id="nestedatt--delivery"></a>
77+
### Nested Schema for `delivery`
78+
79+
Read-Only:
80+
81+
- `compression` (String) The compression method. Valid values are `gzip` or `none`.
82+
- `encoding` (String) The encoding format. Valid values are `json`, `ndjson`, or `proto` (for OTLP).
83+
- `endpoint` (String) The endpoint URL for HTTP and ClickHouse delivery types, or traces endpoint for OTLP.
84+
- `headers` (Map of String) Custom headers to include in HTTP requests.
85+
- `type` (String) The delivery type. Valid values are `http`, `otlphttp`, `clickhouse`, or `internal`.
86+
87+
88+
<a id="nestedatt--sampling"></a>
89+
### Nested Schema for `sampling`
90+
91+
Read-Only:
92+
93+
- `environment` (String) The environment to apply sampling to. Valid values are `production` or `preview`.
94+
- `rate` (Number) The sampling rate from 0 to 1 (e.g., 0.1 for 10%).
95+
- `request_path` (String) Request path prefix to apply the sampling rule to.
96+
- `type` (String) The sampling type. Only `head_sampling` is supported.
97+
98+
99+
<a id="nestedatt--schemas"></a>
100+
### Nested Schema for `schemas`
101+
102+
Read-Only:
103+
104+
- `version` (String)
105+
106+
107+
<a id="nestedatt--transforms"></a>
108+
### Nested Schema for `transforms`
109+
110+
Read-Only:
111+
112+
- `id` (String) The transform ID.

0 commit comments

Comments
 (0)