Skip to content

Commit c69a5fd

Browse files
feat: support pooler data source (#54)
* chore: refactor settings config parse * feat: support pooler data source * chore: update ci workflow * docs: update json schema file * chore: reduce tf version matrix used in tests --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent 5da2a33 commit c69a5fd

File tree

11 files changed

+273
-43
lines changed

11 files changed

+273
-43
lines changed

.github/workflows/generate-json.yml

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,18 @@ jobs:
1919
with:
2020
go-version-file: 'go.mod'
2121
cache: true
22-
- run: go mod download
2322
- run: make generate-json
2423
- run: |
25-
git config --global user.name 'github-schema-bot'
26-
git config --global user.email 'github-schema-bot@supabase.com'
2724
if [[ `git status --porcelain` ]]; then
2825
echo "[bot] Schema changes detected, committing."
29-
git add docs/schema.json
30-
git commit -m "ci: regenerate json schema file"
31-
git push
26+
# git sha != sha1: https://git-scm.com/book/en/v2/Git-Internals-Git-Objects
27+
sha=$(gh api -X GET repos/{owner}/{repo}/contents/$SCHEMA_FILE -F ref='${{ github.head_ref }}' --jq '.sha')
28+
b64=$(cat $SCHEMA_FILE | base64)
29+
gh api -X PUT repos/{owner}/{repo}/contents/$SCHEMA_FILE -F branch='${{ github.head_ref }}' \
30+
-F content="$b64" -F sha="$sha" -F message='docs: update json schema file'
3231
else
3332
echo "[bot] No schema changes detected, nothing to commit."
3433
fi
34+
env:
35+
SCHEMA_FILE: docs/schema.json
36+
GH_TOKEN: ${{ github.token }}

.github/workflows/test.yml

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,7 @@ jobs:
6161
matrix:
6262
# list whatever Terraform versions here you would like to support
6363
terraform:
64-
- '1.0.*'
65-
- '1.1.*'
66-
- '1.2.*'
67-
- '1.3.*'
68-
- '1.4.*'
64+
- '1.7.*'
6965
steps:
7066
- uses: actions/checkout@v4
7167
- uses: actions/setup-go@v5

docs/data-sources/pooler.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "supabase_pooler Data Source - terraform-provider-supabase"
4+
subcategory: ""
5+
description: |-
6+
Pooler data source
7+
---
8+
9+
# supabase_pooler (Data Source)
10+
11+
Pooler data source
12+
13+
## Example Usage
14+
15+
```terraform
16+
data "supabase_pooler" "production" {
17+
project_ref = "mayuaycdtijbctgqbycg"
18+
}
19+
```
20+
21+
<!-- schema generated by tfplugindocs -->
22+
## Schema
23+
24+
### Required
25+
26+
- `project_ref` (String) Project ref
27+
28+
### Read-Only
29+
30+
- `url` (Map of String) Map of pooler mode to connection string

docs/resources/settings.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ resource "supabase_settings" "production" {
3939

4040
- `api` (String) API settings as [serialised JSON](https://api.supabase.com/api/v1#/services/updatePostgRESTConfig)
4141
- `auth` (String) Auth settings as [serialised JSON](https://api.supabase.com/api/v1#/projects%20config/updateV1AuthConfig)
42+
- `database` (String) Database settings as serialised JSON
43+
- `network` (String) Network settings as serialised JSON
4244
- `pooler` (String) Pooler settings as serialised JSON
4345
- `storage` (String) Storage settings as serialised JSON
4446

docs/schema.json

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,12 +173,24 @@
173173
"description_kind": "markdown",
174174
"optional": true
175175
},
176+
"database": {
177+
"type": "string",
178+
"description": "Database settings as serialised JSON",
179+
"description_kind": "markdown",
180+
"optional": true
181+
},
176182
"id": {
177183
"type": "string",
178184
"description": "Project identifier",
179185
"description_kind": "markdown",
180186
"computed": true
181187
},
188+
"network": {
189+
"type": "string",
190+
"description": "Network settings as serialised JSON",
191+
"description_kind": "markdown",
192+
"optional": true
193+
},
182194
"pooler": {
183195
"type": "string",
184196
"description": "Pooler settings as serialised JSON",
@@ -246,6 +258,30 @@
246258
"description": "Branch data source",
247259
"description_kind": "markdown"
248260
}
261+
},
262+
"supabase_pooler": {
263+
"version": 0,
264+
"block": {
265+
"attributes": {
266+
"project_ref": {
267+
"type": "string",
268+
"description": "Project ref",
269+
"description_kind": "markdown",
270+
"required": true
271+
},
272+
"url": {
273+
"type": [
274+
"map",
275+
"string"
276+
],
277+
"description": "Map of pooler mode to connection string",
278+
"description_kind": "markdown",
279+
"computed": true
280+
}
281+
},
282+
"description": "Pooler data source",
283+
"description_kind": "markdown"
284+
}
249285
}
250286
}
251287
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
data "supabase_pooler" "production" {
2+
project_ref = "mayuaycdtijbctgqbycg"
3+
}

examples/examples.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,6 @@ var (
1111
BranchResourceConfig string
1212
//go:embed data-sources/supabase_branch/data-source.tf
1313
BranchDataSourceConfig string
14+
//go:embed data-sources/supabase_pooler/data-source.tf
15+
PoolerDataSourceConfig string
1416
)
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package provider
5+
6+
import (
7+
"context"
8+
"fmt"
9+
10+
"github.com/hashicorp/terraform-plugin-framework/datasource"
11+
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
12+
"github.com/hashicorp/terraform-plugin-framework/path"
13+
"github.com/hashicorp/terraform-plugin-framework/types"
14+
"github.com/hashicorp/terraform-plugin-log/tflog"
15+
"github.com/supabase/cli/pkg/api"
16+
)
17+
18+
// Ensure provider defined types fully satisfy framework interfaces.
19+
var _ datasource.DataSource = &PoolerDataSource{}
20+
21+
func NewPoolerDataSource() datasource.DataSource {
22+
return &PoolerDataSource{}
23+
}
24+
25+
// PoolerDataSource defines the data source implementation.
26+
type PoolerDataSource struct {
27+
client *api.ClientWithResponses
28+
}
29+
30+
// PoolerDataSourceModel describes the data source data model.
31+
type PoolerDataSourceModel struct {
32+
ProjectRef types.String `tfsdk:"project_ref"`
33+
Url types.MapType `tfsdk:"url"`
34+
}
35+
36+
func (d *PoolerDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
37+
resp.TypeName = req.ProviderTypeName + "_pooler"
38+
}
39+
40+
func (d *PoolerDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
41+
resp.Schema = schema.Schema{
42+
// This description is used by the documentation generator and the language server.
43+
MarkdownDescription: "Pooler data source",
44+
45+
Attributes: map[string]schema.Attribute{
46+
"project_ref": schema.StringAttribute{
47+
MarkdownDescription: "Project ref",
48+
Required: true,
49+
},
50+
"url": schema.MapAttribute{
51+
MarkdownDescription: "Map of pooler mode to connection string",
52+
Computed: true,
53+
ElementType: types.StringType,
54+
},
55+
},
56+
}
57+
}
58+
59+
func (d *PoolerDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
60+
// Prevent panic if the provider has not been configured.
61+
if req.ProviderData == nil {
62+
return
63+
}
64+
65+
client, ok := req.ProviderData.(*api.ClientWithResponses)
66+
67+
if !ok {
68+
resp.Diagnostics.AddError(
69+
"Unexpected Data Source Configure Type",
70+
fmt.Sprintf("Expected *api.ClientWithResponses, got: %T. Please report this issue to the provider developers.", req.ProviderData),
71+
)
72+
73+
return
74+
}
75+
76+
d.client = client
77+
}
78+
79+
func (d *PoolerDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
80+
var projectRef types.String
81+
82+
// Read Terraform configuration data into the model
83+
resp.Diagnostics.Append(req.Config.GetAttribute(ctx, path.Root("project_ref"), &projectRef)...)
84+
if resp.Diagnostics.HasError() {
85+
return
86+
}
87+
88+
// If applicable, this is a great opportunity to initialize any necessary
89+
// provider client data and make a call using it.
90+
httpResp, err := d.client.V1GetPgbouncerConfigWithResponse(ctx, projectRef.ValueString())
91+
if err != nil {
92+
msg := fmt.Sprintf("Unable to read pooler, got error: %s", err)
93+
resp.Diagnostics.AddError("Client Error", msg)
94+
return
95+
}
96+
if httpResp.JSON200 == nil {
97+
msg := fmt.Sprintf("Unable to read pooler, got status %d: %s", httpResp.StatusCode(), httpResp.Body)
98+
resp.Diagnostics.AddError("Client Error", msg)
99+
return
100+
}
101+
102+
url := map[string]string{}
103+
if httpResp.JSON200.PoolMode != nil && httpResp.JSON200.ConnectionString != nil {
104+
mode := string(*httpResp.JSON200.PoolMode)
105+
url[mode] = *httpResp.JSON200.ConnectionString
106+
}
107+
108+
// Write logs using the tflog package
109+
// Documentation: https://terraform.io/plugin/log
110+
tflog.Trace(ctx, "read a data source")
111+
112+
// Save data into Terraform state
113+
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("url"), url)...)
114+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package provider
5+
6+
import (
7+
"net/http"
8+
"testing"
9+
10+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
11+
"github.com/supabase/cli/pkg/api"
12+
"github.com/supabase/terraform-provider-supabase/examples"
13+
"gopkg.in/h2non/gock.v1"
14+
)
15+
16+
func TestAccPoolerDataSource(t *testing.T) {
17+
poolerUrl := "postgres://user:pass@db.supabase.co:5432/postgres"
18+
// Setup mock api
19+
defer gock.OffAll()
20+
gock.New("https://api.supabase.com").
21+
Get("/v1/projects/mayuaycdtijbctgqbycg/config/database/pgbouncer").
22+
Times(3).
23+
Reply(http.StatusOK).
24+
JSON(api.V1PgbouncerConfigResponse{
25+
ConnectionString: &poolerUrl,
26+
DefaultPoolSize: Ptr(float32(15)),
27+
IgnoreStartupParameters: Ptr(""),
28+
MaxClientConn: Ptr(float32(200)),
29+
PoolMode: Ptr(api.Transaction),
30+
})
31+
// Run test
32+
resource.Test(t, resource.TestCase{
33+
PreCheck: func() { testAccPreCheck(t) },
34+
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
35+
Steps: []resource.TestStep{
36+
// Read testing
37+
{
38+
Config: examples.PoolerDataSourceConfig,
39+
Check: resource.ComposeAggregateTestCheckFunc(
40+
resource.TestCheckResourceAttr("data.supabase_pooler.production", "url.transaction", poolerUrl),
41+
),
42+
},
43+
},
44+
})
45+
}

internal/provider/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ func (p *SupabaseProvider) Resources(ctx context.Context) []func() resource.Reso
9595
func (p *SupabaseProvider) DataSources(ctx context.Context) []func() datasource.DataSource {
9696
return []func() datasource.DataSource{
9797
NewBranchDataSource,
98+
NewPoolerDataSource,
9899
}
99100
}
100101

0 commit comments

Comments
 (0)