这是indexloc提供的服务,不要输入任何密码
Skip to content

Add support for creating Edge Config #161

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions client/edge_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package client

import (
"context"
"fmt"

"github.com/hashicorp/terraform-plugin-log/tflog"
)

type EdgeConfig struct {
Slug string `json:"slug"`
ID string `json:"id"`
TeamID string `json:"ownerId"`
}

type CreateEdgeConfigRequest struct {
Name string `json:"slug"`
TeamID string `json:"-"`
}

func (c *Client) CreateEdgeConfig(ctx context.Context, request CreateEdgeConfigRequest) (e *EdgeConfig, err error) {
url := fmt.Sprintf("%s/v1/edge-config", c.baseURL)
if c.teamID(request.TeamID) != "" {
url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(request.TeamID))
}
payload := string(mustMarshal(request))
tflog.Trace(ctx, "creating edge config", map[string]interface{}{
"url": url,
"payload": payload,
})
err = c.doRequest(clientRequest{
ctx: ctx,
method: "POST",
url: url,
body: payload,
}, &e)
return e, err
}

func (c *Client) GetEdgeConfig(ctx context.Context, id, teamID string) (e *EdgeConfig, err error) {
url := fmt.Sprintf("%s/v1/edge-config/%s", c.baseURL, id)
if c.teamID(teamID) != "" {
url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(teamID))
}
tflog.Trace(ctx, "reading edge config", map[string]interface{}{
"url": url,
})
err = c.doRequest(clientRequest{
ctx: ctx,
method: "GET",
url: url,
}, &e)
return e, err
}

func (c *Client) DeleteEdgeConfig(ctx context.Context, id, teamID string) error {
url := fmt.Sprintf("%s/v1/edge-config/%s", c.baseURL, id)
if c.teamID(teamID) != "" {
url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(teamID))
}
tflog.Trace(ctx, "deleting edge config", map[string]interface{}{
"url": url,
})

return c.doRequest(clientRequest{
ctx: ctx,
method: "DELETE",
url: url,
}, nil)
}
31 changes: 31 additions & 0 deletions docs/data-sources/edge_config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "vercel_edge_config Data Source - terraform-provider-vercel"
subcategory: ""
description: |-
Provides information about an existing Edge Config resource.
An Edge Config is a global data store that enables experimentation with feature flags, A/B testing, critical redirects, and more.
---

# vercel_edge_config (Data Source)

Provides information about an existing Edge Config resource.

An Edge Config is a global data store that enables experimentation with feature flags, A/B testing, critical redirects, and more.



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

### Required

- `id` (String) The Edge Config ID to be retrieved. This can be found by navigating to the Edge Config in the Vercel UI and looking at the URL. It should begin with `ecfg_`.

### Optional

- `team_id` (String) The ID of the team the Edge Config should exist under. Required when configuring a team resource if a default team has not been set in the provider.

### Read-Only

- `name` (String) The name/slug of the Edge Config.
53 changes: 53 additions & 0 deletions docs/resources/edge_config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "vercel_edge_config Resource - terraform-provider-vercel"
subcategory: ""
description: |-
Provides an Edge Config resource.
An Edge Config is a global data store that enables experimentation with feature flags, A/B testing, critical redirects, and more.
---

# vercel_edge_config (Resource)

Provides an Edge Config resource.

An Edge Config is a global data store that enables experimentation with feature flags, A/B testing, critical redirects, and more.

## Example Usage

```terraform
resource "vercel_edge_config" "example" {
name = "my-edge-config"
}
```

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

### Required

- `name` (String) The name/slug of the Edge Config.

### Optional

- `team_id` (String) The ID of the team the Edge Config should exist under. Required when configuring a team resource if a default team has not been set in the provider.

### Read-Only

- `id` (String) The ID of this resource.

## Import

Import is supported using the following syntax:

```shell
# If importing into a personal account, or with a team configured on
# the provider, simply use the edge config id.
# - edge_config_id is hard to find, but can be found by navigating to the Edge Config in the Vercel UI and looking at the URL. It should begin with `ecfg_`.
terraform import vercel_edge_config.example ecfg_xxxxxxxxxxxxxxxxxxxxxxxxxxxx

# Alternatively, you can import via the team_id and edge_config_id.
# - team_id can be found in the team `settings` tab in the Vercel UI.
# - edge_config_id is hard to find, but can be found by navigating to the Edge Config in the Vercel UI and looking at the URL. It should begin with `ecfg_`.
terraform import vercel_edge_config.example team_xxxxxxxxxxxxxxxxxxxxxxxx/ecfg_xxxxxxxxxxxxxxxxxxxxxxxxxxxx
```
3 changes: 3 additions & 0 deletions examples/data-sources/vercel_dns_record/data-source.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
data "vercel_edge_config" "example" {
id = "ecfg_xxxxxxxxxxxxxxxxxxxxxxxx"
}
9 changes: 9 additions & 0 deletions examples/resources/vercel_edge_config/import.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# If importing into a personal account, or with a team configured on
# the provider, simply use the edge config id.
# - edge_config_id is hard to find, but can be found by navigating to the Edge Config in the Vercel UI and looking at the URL. It should begin with `ecfg_`.
terraform import vercel_edge_config.example ecfg_xxxxxxxxxxxxxxxxxxxxxxxxxxxx

# Alternatively, you can import via the team_id and edge_config_id.
# - team_id can be found in the team `settings` tab in the Vercel UI.
# - edge_config_id is hard to find, but can be found by navigating to the Edge Config in the Vercel UI and looking at the URL. It should begin with `ecfg_`.
terraform import vercel_edge_config.example team_xxxxxxxxxxxxxxxxxxxxxxxx/ecfg_xxxxxxxxxxxxxxxxxxxxxxxxxxxx
3 changes: 3 additions & 0 deletions examples/resources/vercel_edge_config/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
resource "vercel_edge_config" "example" {
name = "my-edge-config"
}
113 changes: 113 additions & 0 deletions vercel/data_source_edge_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package vercel

import (
"context"
"fmt"

"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/vercel/terraform-provider-vercel/client"
)

// Ensure the implementation satisfies the expected interfaces.
var (
_ datasource.DataSource = &edgeConfigDataSource{}
_ datasource.DataSourceWithConfigure = &edgeConfigDataSource{}
)

func newEdgeConfigDataSource() datasource.DataSource {
return &edgeConfigDataSource{}
}

type edgeConfigDataSource struct {
client *client.Client
}

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

func (d *edgeConfigDataSource) 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.(*client.Client)
if !ok {
resp.Diagnostics.AddError(
"Unexpected Data Source Configure Type",
fmt.Sprintf("Expected *client.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData),
)
return
}

d.client = client
}

// Schema returns the schema information for an edgeConfig data source
func (r *edgeConfigDataSource) Schema(_ context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Description: `
Provides information about an existing Edge Config resource.

An Edge Config is a global data store that enables experimentation with feature flags, A/B testing, critical redirects, and more.`,
Attributes: map[string]schema.Attribute{
"team_id": schema.StringAttribute{
Optional: true,
Computed: true,
Description: "The ID of the team the Edge Config should exist under. Required when configuring a team resource if a default team has not been set in the provider.",
},
"id": schema.StringAttribute{
Required: true,
Description: "The Edge Config ID to be retrieved. This can be found by navigating to the Edge Config in the Vercel UI and looking at the URL. It should begin with `ecfg_`.",
},
"name": schema.StringAttribute{
Computed: true,
Description: "The name/slug of the Edge Config.",
},
},
}
}

// Read will read the edgeConfig information by requesting it from the Vercel API, and will update terraform
// with this information.
// It is called by the provider whenever data source values should be read to update state.
func (d *edgeConfigDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var config EdgeConfig
diags := req.Config.Get(ctx, &config)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

out, err := d.client.GetEdgeConfig(ctx, config.ID.ValueString(), config.TeamID.ValueString())
if client.NotFound(err) {
resp.State.RemoveResource(ctx)
return
}
if err != nil {
resp.Diagnostics.AddError(
"Error reading EdgeConfig",
fmt.Sprintf("Could not get Edge Config %s %s, unexpected error: %s",
config.TeamID.ValueString(),
config.ID.ValueString(),
err,
),
)
return
}

result := responseToEdgeConfig(out)
tflog.Trace(ctx, "read edge config", map[string]interface{}{
"team_id": result.TeamID.ValueString(),
"edge_config_id": result.ID.ValueString(),
})

diags = resp.State.Set(ctx, result)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
}
39 changes: 39 additions & 0 deletions vercel/data_source_edge_config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package vercel_test

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/acctest"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
)

func TestAcc_EdgeConfigDataSource(t *testing.T) {
name := acctest.RandString(16)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccEdgeConfigDataSourceConfig(name, teamIDConfig()),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("data.vercel_edge_config.test", "name", name),
),
},
},
})
}

func testAccEdgeConfigDataSourceConfig(name, teamID string) string {
return fmt.Sprintf(`
resource "vercel_edge_config" "test" {
name = "%[1]s"
%[2]s
}

data "vercel_edge_config" "test" {
id = vercel_edge_config.test.id
%[2]s
}
`, name, teamID)
}
2 changes: 2 additions & 0 deletions vercel/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ func (p *vercelProvider) Resources(_ context.Context) []func() resource.Resource
newProjectDomainResource,
newProjectEnvironmentVariableResource,
newSharedEnvironmentVariableResource,
newEdgeConfigResource,
}
}

Expand All @@ -68,6 +69,7 @@ func (p *vercelProvider) DataSources(_ context.Context) []func() datasource.Data
newProjectDataSource,
newProjectDirectoryDataSource,
newSharedEnvironmentVariableDataSource,
newEdgeConfigDataSource,
}
}

Expand Down
Loading