Skip to content

Commit

Permalink
feat: support pooler data source (#54)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
sweatybridge and github-actions[bot] authored Mar 28, 2024
1 parent 5da2a33 commit c69a5fd
Show file tree
Hide file tree
Showing 11 changed files with 273 additions and 43 deletions.
14 changes: 8 additions & 6 deletions .github/workflows/generate-json.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,18 @@ jobs:
with:
go-version-file: 'go.mod'
cache: true
- run: go mod download
- run: make generate-json
- run: |
git config --global user.name 'github-schema-bot'
git config --global user.email 'github-schema-bot@supabase.com'
if [[ `git status --porcelain` ]]; then
echo "[bot] Schema changes detected, committing."
git add docs/schema.json
git commit -m "ci: regenerate json schema file"
git push
# git sha != sha1: https://git-scm.com/book/en/v2/Git-Internals-Git-Objects
sha=$(gh api -X GET repos/{owner}/{repo}/contents/$SCHEMA_FILE -F ref='${{ github.head_ref }}' --jq '.sha')
b64=$(cat $SCHEMA_FILE | base64)
gh api -X PUT repos/{owner}/{repo}/contents/$SCHEMA_FILE -F branch='${{ github.head_ref }}' \
-F content="$b64" -F sha="$sha" -F message='docs: update json schema file'
else
echo "[bot] No schema changes detected, nothing to commit."
fi
env:
SCHEMA_FILE: docs/schema.json
GH_TOKEN: ${{ github.token }}
6 changes: 1 addition & 5 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,7 @@ jobs:
matrix:
# list whatever Terraform versions here you would like to support
terraform:
- '1.0.*'
- '1.1.*'
- '1.2.*'
- '1.3.*'
- '1.4.*'
- '1.7.*'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
Expand Down
30 changes: 30 additions & 0 deletions docs/data-sources/pooler.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "supabase_pooler Data Source - terraform-provider-supabase"
subcategory: ""
description: |-
Pooler data source
---

# supabase_pooler (Data Source)

Pooler data source

## Example Usage

```terraform
data "supabase_pooler" "production" {
project_ref = "mayuaycdtijbctgqbycg"
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `project_ref` (String) Project ref

### Read-Only

- `url` (Map of String) Map of pooler mode to connection string
2 changes: 2 additions & 0 deletions docs/resources/settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ resource "supabase_settings" "production" {

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

Expand Down
36 changes: 36 additions & 0 deletions docs/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -173,12 +173,24 @@
"description_kind": "markdown",
"optional": true
},
"database": {
"type": "string",
"description": "Database settings as serialised JSON",
"description_kind": "markdown",
"optional": true
},
"id": {
"type": "string",
"description": "Project identifier",
"description_kind": "markdown",
"computed": true
},
"network": {
"type": "string",
"description": "Network settings as serialised JSON",
"description_kind": "markdown",
"optional": true
},
"pooler": {
"type": "string",
"description": "Pooler settings as serialised JSON",
Expand Down Expand Up @@ -246,6 +258,30 @@
"description": "Branch data source",
"description_kind": "markdown"
}
},
"supabase_pooler": {
"version": 0,
"block": {
"attributes": {
"project_ref": {
"type": "string",
"description": "Project ref",
"description_kind": "markdown",
"required": true
},
"url": {
"type": [
"map",
"string"
],
"description": "Map of pooler mode to connection string",
"description_kind": "markdown",
"computed": true
}
},
"description": "Pooler data source",
"description_kind": "markdown"
}
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions examples/data-sources/supabase_pooler/data-source.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
data "supabase_pooler" "production" {
project_ref = "mayuaycdtijbctgqbycg"
}
2 changes: 2 additions & 0 deletions examples/examples.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ var (
BranchResourceConfig string
//go:embed data-sources/supabase_branch/data-source.tf
BranchDataSourceConfig string
//go:embed data-sources/supabase_pooler/data-source.tf
PoolerDataSourceConfig string
)
114 changes: 114 additions & 0 deletions internal/provider/pooler_data_source.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package provider

import (
"context"
"fmt"

"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/supabase/cli/pkg/api"
)

// Ensure provider defined types fully satisfy framework interfaces.
var _ datasource.DataSource = &PoolerDataSource{}

func NewPoolerDataSource() datasource.DataSource {
return &PoolerDataSource{}
}

// PoolerDataSource defines the data source implementation.
type PoolerDataSource struct {
client *api.ClientWithResponses
}

// PoolerDataSourceModel describes the data source data model.
type PoolerDataSourceModel struct {
ProjectRef types.String `tfsdk:"project_ref"`
Url types.MapType `tfsdk:"url"`
}

func (d *PoolerDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_pooler"
}

func (d *PoolerDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
// This description is used by the documentation generator and the language server.
MarkdownDescription: "Pooler data source",

Attributes: map[string]schema.Attribute{
"project_ref": schema.StringAttribute{
MarkdownDescription: "Project ref",
Required: true,
},
"url": schema.MapAttribute{
MarkdownDescription: "Map of pooler mode to connection string",
Computed: true,
ElementType: types.StringType,
},
},
}
}

func (d *PoolerDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
// Prevent panic if the provider has not been configured.
if req.ProviderData == nil {
return
}

client, ok := req.ProviderData.(*api.ClientWithResponses)

if !ok {
resp.Diagnostics.AddError(
"Unexpected Data Source Configure Type",
fmt.Sprintf("Expected *api.ClientWithResponses, got: %T. Please report this issue to the provider developers.", req.ProviderData),
)

return
}

d.client = client
}

func (d *PoolerDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var projectRef types.String

// Read Terraform configuration data into the model
resp.Diagnostics.Append(req.Config.GetAttribute(ctx, path.Root("project_ref"), &projectRef)...)
if resp.Diagnostics.HasError() {
return
}

// If applicable, this is a great opportunity to initialize any necessary
// provider client data and make a call using it.
httpResp, err := d.client.V1GetPgbouncerConfigWithResponse(ctx, projectRef.ValueString())
if err != nil {
msg := fmt.Sprintf("Unable to read pooler, got error: %s", err)
resp.Diagnostics.AddError("Client Error", msg)
return
}
if httpResp.JSON200 == nil {
msg := fmt.Sprintf("Unable to read pooler, got status %d: %s", httpResp.StatusCode(), httpResp.Body)
resp.Diagnostics.AddError("Client Error", msg)
return
}

url := map[string]string{}
if httpResp.JSON200.PoolMode != nil && httpResp.JSON200.ConnectionString != nil {
mode := string(*httpResp.JSON200.PoolMode)
url[mode] = *httpResp.JSON200.ConnectionString
}

// Write logs using the tflog package
// Documentation: https://terraform.io/plugin/log
tflog.Trace(ctx, "read a data source")

// Save data into Terraform state
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("url"), url)...)
}
45 changes: 45 additions & 0 deletions internal/provider/pooler_data_source_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package provider

import (
"net/http"
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/supabase/cli/pkg/api"
"github.com/supabase/terraform-provider-supabase/examples"
"gopkg.in/h2non/gock.v1"
)

func TestAccPoolerDataSource(t *testing.T) {
poolerUrl := "postgres://user:pass@db.supabase.co:5432/postgres"
// Setup mock api
defer gock.OffAll()
gock.New("https://api.supabase.com").
Get("/v1/projects/mayuaycdtijbctgqbycg/config/database/pgbouncer").
Times(3).
Reply(http.StatusOK).
JSON(api.V1PgbouncerConfigResponse{
ConnectionString: &poolerUrl,
DefaultPoolSize: Ptr(float32(15)),
IgnoreStartupParameters: Ptr(""),
MaxClientConn: Ptr(float32(200)),
PoolMode: Ptr(api.Transaction),
})
// Run test
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
// Read testing
{
Config: examples.PoolerDataSourceConfig,
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("data.supabase_pooler.production", "url.transaction", poolerUrl),
),
},
},
})
}
1 change: 1 addition & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ func (p *SupabaseProvider) Resources(ctx context.Context) []func() resource.Reso
func (p *SupabaseProvider) DataSources(ctx context.Context) []func() datasource.DataSource {
return []func() datasource.DataSource{
NewBranchDataSource,
NewPoolerDataSource,
}
}

Expand Down
Loading

0 comments on commit c69a5fd

Please sign in to comment.