From c46f19c1258a58ab75db7ef70913884bd27a3070 Mon Sep 17 00:00:00 2001 From: Douglas Harcourt Parsons Date: Mon, 15 Apr 2024 17:58:50 +0100 Subject: [PATCH] Add support for Edge Config Schema - Change TF_LOG levels to Info, rather than Trace (trace is used very heavily by the provider protocol, so it's too noisy). --- client/alias_create.go | 2 +- client/alias_delete.go | 2 +- client/alias_get.go | 2 +- client/deployment_create.go | 2 +- client/deployment_delete.go | 2 +- client/deployment_get.go | 2 +- client/dns_record_update.go | 2 +- client/edge_config.go | 22 +- client/edge_config_schema.go | 78 +++++ client/edge_config_token.go | 6 +- client/environment_variable_create.go | 4 +- client/environment_variable_update.go | 2 +- client/environment_variables_delete.go | 2 +- client/environment_variables_get.go | 4 +- client/error.go | 5 + client/file_create.go | 4 +- client/project_create.go | 2 +- client/project_delete.go | 2 +- client/project_domain_create.go | 2 +- client/project_domain_delete.go | 2 +- client/project_domain_get.go | 2 +- client/project_domain_update.go | 2 +- client/project_get.go | 2 +- client/project_list.go | 2 +- client/project_update.go | 2 +- client/project_update_production_branch.go | 2 +- client/request.go | 25 +- client/shared_environment_variable_create.go | 2 +- client/shared_environment_variable_delete.go | 2 +- client/shared_environment_variable_get.go | 2 +- client/shared_environment_variable_list.go | 2 +- client/shared_environment_variable_update.go | 2 +- client/team_create.go | 2 +- client/team_delete.go | 2 +- client/team_get.go | 2 +- docs/data-sources/edge_config_schema.md | 34 ++ docs/resources/edge_config_schema.md | 63 ++++ docs/resources/edge_config_token.md | 2 +- .../vercel_edge_config_schema/data-source.tf | 3 + .../vercel_edge_config_schema/import.sh | 9 + .../vercel_edge_config_schema/resource.tf | 19 ++ sweep/main.go | 21 ++ vercel/data_source_alias.go | 2 +- vercel/data_source_edge_config.go | 6 +- vercel/data_source_edge_config_schema.go | 119 +++++++ vercel/data_source_edge_config_schema_test.go | 77 +++++ vercel/data_source_edge_config_token.go | 6 +- vercel/data_source_project.go | 2 +- ...data_source_shared_environment_variable.go | 4 +- vercel/provider.go | 2 + vercel/resource_alias.go | 6 +- vercel/resource_alias_test.go | 2 +- vercel/resource_deployment.go | 8 +- vercel/resource_dns_record.go | 8 +- vercel/resource_edge_config.go | 8 +- vercel/resource_edge_config_schema.go | 307 ++++++++++++++++++ vercel/resource_edge_config_schema_test.go | 151 +++++++++ vercel/resource_edge_config_test.go | 2 +- vercel/resource_edge_config_token.go | 10 +- vercel/resource_edge_config_token_test.go | 2 +- vercel/resource_project.go | 20 +- vercel/resource_project_domain.go | 10 +- .../resource_project_environment_variable.go | 10 +- .../resource_shared_environment_variable.go | 10 +- vercel/validator_json_string.go | 41 +++ 65 files changed, 1057 insertions(+), 109 deletions(-) create mode 100644 client/edge_config_schema.go create mode 100644 docs/data-sources/edge_config_schema.md create mode 100644 docs/resources/edge_config_schema.md create mode 100644 examples/data-sources/vercel_edge_config_schema/data-source.tf create mode 100644 examples/resources/vercel_edge_config_schema/import.sh create mode 100644 examples/resources/vercel_edge_config_schema/resource.tf create mode 100644 vercel/data_source_edge_config_schema.go create mode 100644 vercel/data_source_edge_config_schema_test.go create mode 100644 vercel/resource_edge_config_schema.go create mode 100644 vercel/resource_edge_config_schema_test.go create mode 100644 vercel/validator_json_string.go diff --git a/client/alias_create.go b/client/alias_create.go index 0d6c55c2..319cc7da 100644 --- a/client/alias_create.go +++ b/client/alias_create.go @@ -27,7 +27,7 @@ func (c *Client) CreateAlias(ctx context.Context, request CreateAliasRequest, de } payload := string(mustMarshal(request)) - tflog.Trace(ctx, "creating alias", map[string]interface{}{ + tflog.Info(ctx, "creating alias", map[string]interface{}{ "url": url, "payload": payload, }) diff --git a/client/alias_delete.go b/client/alias_delete.go index b6012dcb..d30d2b5c 100644 --- a/client/alias_delete.go +++ b/client/alias_delete.go @@ -19,7 +19,7 @@ func (c *Client) DeleteAlias(ctx context.Context, aliasUID string, teamID string url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(teamID)) } - tflog.Trace(ctx, "deleting alias", map[string]interface{}{ + tflog.Info(ctx, "deleting alias", map[string]interface{}{ "url": url, }) err = c.doRequest(clientRequest{ diff --git a/client/alias_get.go b/client/alias_get.go index c61924b5..77cd99e1 100644 --- a/client/alias_get.go +++ b/client/alias_get.go @@ -21,7 +21,7 @@ func (c *Client) GetAlias(ctx context.Context, alias, teamID string) (r AliasRes if c.teamID(teamID) != "" { url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(teamID)) } - tflog.Trace(ctx, "getting alias", map[string]interface{}{ + tflog.Info(ctx, "getting alias", map[string]interface{}{ "url": url, }) err = c.doRequest(clientRequest{ diff --git a/client/deployment_create.go b/client/deployment_create.go index 2fa83076..5909cdea 100644 --- a/client/deployment_create.go +++ b/client/deployment_create.go @@ -201,7 +201,7 @@ func (c *Client) CreateDeployment(ctx context.Context, request CreateDeploymentR } payload := string(mustMarshal(request)) - tflog.Trace(ctx, "creating deployment", map[string]interface{}{ + tflog.Info(ctx, "creating deployment", map[string]interface{}{ "url": url, "payload": payload, }) diff --git a/client/deployment_delete.go b/client/deployment_delete.go index 9367d280..cc8a8690 100644 --- a/client/deployment_delete.go +++ b/client/deployment_delete.go @@ -20,7 +20,7 @@ func (c *Client) DeleteDeployment(ctx context.Context, deploymentID string, team url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(teamID)) } - tflog.Trace(ctx, "deleting deployment", map[string]interface{}{ + tflog.Info(ctx, "deleting deployment", map[string]interface{}{ "url": url, }) err = c.doRequest(clientRequest{ diff --git a/client/deployment_get.go b/client/deployment_get.go index 034ed1ab..25a3ebb2 100644 --- a/client/deployment_get.go +++ b/client/deployment_get.go @@ -14,7 +14,7 @@ func (c *Client) GetDeployment(ctx context.Context, deploymentID, teamID string) url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(teamID)) } - tflog.Trace(ctx, "getting deployment", map[string]interface{}{ + tflog.Info(ctx, "getting deployment", map[string]interface{}{ "url": url, }) err = c.doRequest(clientRequest{ diff --git a/client/dns_record_update.go b/client/dns_record_update.go index addaf515..83ca6c00 100644 --- a/client/dns_record_update.go +++ b/client/dns_record_update.go @@ -33,7 +33,7 @@ func (c *Client) UpdateDNSRecord(ctx context.Context, teamID, recordID string, r } payload := string(mustMarshal(request)) - tflog.Trace(ctx, "updating DNS record", map[string]interface{}{ + tflog.Info(ctx, "updating DNS record", map[string]interface{}{ "url": url, "payload": payload, }) diff --git a/client/edge_config.go b/client/edge_config.go index 4e61f2c6..d81846c8 100644 --- a/client/edge_config.go +++ b/client/edge_config.go @@ -24,7 +24,7 @@ func (c *Client) CreateEdgeConfig(ctx context.Context, request CreateEdgeConfigR url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(request.TeamID)) } payload := string(mustMarshal(request)) - tflog.Trace(ctx, "creating edge config", map[string]interface{}{ + tflog.Info(ctx, "creating edge config", map[string]interface{}{ "url": url, "payload": payload, }) @@ -42,7 +42,7 @@ func (c *Client) GetEdgeConfig(ctx context.Context, id, teamID string) (e EdgeCo if c.teamID(teamID) != "" { url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(teamID)) } - tflog.Trace(ctx, "reading edge config", map[string]interface{}{ + tflog.Info(ctx, "reading edge config", map[string]interface{}{ "url": url, }) err = c.doRequest(clientRequest{ @@ -84,7 +84,7 @@ func (c *Client) DeleteEdgeConfig(ctx context.Context, id, teamID string) error if c.teamID(teamID) != "" { url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(teamID)) } - tflog.Trace(ctx, "deleting edge config", map[string]interface{}{ + tflog.Info(ctx, "deleting edge config", map[string]interface{}{ "url": url, }) @@ -94,3 +94,19 @@ func (c *Client) DeleteEdgeConfig(ctx context.Context, id, teamID string) error url: url, }, nil) } + +func (c *Client) ListEdgeConfigs(ctx context.Context, teamID string) (e []EdgeConfig, err error) { + url := fmt.Sprintf("%s/v1/edge-config", c.baseURL) + if c.teamID(teamID) != "" { + url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(teamID)) + } + tflog.Info(ctx, "listing edge configs", map[string]interface{}{ + "url": url, + }) + err = c.doRequest(clientRequest{ + ctx: ctx, + method: "GET", + url: url, + }, &e) + return e, err +} diff --git a/client/edge_config_schema.go b/client/edge_config_schema.go new file mode 100644 index 00000000..582866b1 --- /dev/null +++ b/client/edge_config_schema.go @@ -0,0 +1,78 @@ +package client + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-log/tflog" +) + +type EdgeConfigSchema struct { + ID string `json:"-"` + Definition any `json:"definition"` + TeamID string `json:"-"` +} + +func (c *Client) UpsertEdgeConfigSchema(ctx context.Context, request EdgeConfigSchema) (e EdgeConfigSchema, err error) { + url := fmt.Sprintf("%s/v1/edge-config/%s/schema", c.baseURL, request.ID) + if c.teamID(request.TeamID) != "" { + url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(request.TeamID)) + } + payload := string(mustMarshal(request)) + tflog.Info(ctx, "creating edge config schema", map[string]interface{}{ + "url": url, + "payload": payload, + }) + err = c.doRequest(clientRequest{ + ctx: ctx, + method: "POST", + url: url, + body: payload, + }, &e) + e.TeamID = c.teamID(request.TeamID) + e.ID = request.ID + return e, err +} + +func (c *Client) GetEdgeConfigSchema(ctx context.Context, id, teamID string) (e EdgeConfigSchema, err error) { + url := fmt.Sprintf("%s/v1/edge-config/%s/schema", c.baseURL, id) + if c.teamID(teamID) != "" { + url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(teamID)) + } + tflog.Info(ctx, "getting edge config schema", map[string]interface{}{ + "url": url, + }) + err = c.doRequest(clientRequest{ + ctx: ctx, + method: "GET", + url: url, + errorOnNoContent: true, + }, &e) + + if noContent(err) { + return e, APIError{ + StatusCode: 404, + Message: "Edge Config Schema not found", + Code: "not_found", + } + } + + e.TeamID = c.teamID(teamID) + e.ID = id + return e, err +} + +func (c *Client) DeleteEdgeConfigSchema(ctx context.Context, id, teamID string) error { + url := fmt.Sprintf("%s/v1/edge-config/%s/schema", c.baseURL, id) + if c.teamID(teamID) != "" { + url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(teamID)) + } + tflog.Info(ctx, "deleting edge config schema", map[string]interface{}{ + "url": url, + }) + return c.doRequest(clientRequest{ + ctx: ctx, + method: "DELETE", + url: url, + }, nil) +} diff --git a/client/edge_config_token.go b/client/edge_config_token.go index da08339d..10f59179 100644 --- a/client/edge_config_token.go +++ b/client/edge_config_token.go @@ -35,7 +35,7 @@ func (c *Client) CreateEdgeConfigToken(ctx context.Context, request CreateEdgeCo url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(request.TeamID)) } payload := string(mustMarshal(request)) - tflog.Trace(ctx, "creating edge config token", map[string]interface{}{ + tflog.Info(ctx, "creating edge config token", map[string]interface{}{ "url": url, "payload": payload, }) @@ -70,7 +70,7 @@ func (c *Client) DeleteEdgeConfigToken(ctx context.Context, request EdgeConfigTo }, )) - tflog.Trace(ctx, "deleting edge config token", map[string]interface{}{ + tflog.Info(ctx, "deleting edge config token", map[string]interface{}{ "url": url, "payload": payload, }) @@ -88,7 +88,7 @@ func (c *Client) GetEdgeConfigToken(ctx context.Context, request EdgeConfigToken url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(request.TeamID)) } - tflog.Trace(ctx, "getting edge config token", map[string]interface{}{ + tflog.Info(ctx, "getting edge config token", map[string]interface{}{ "url": url, }) diff --git a/client/environment_variable_create.go b/client/environment_variable_create.go index f0ed920e..c30f80fc 100644 --- a/client/environment_variable_create.go +++ b/client/environment_variable_create.go @@ -31,7 +31,7 @@ func (c *Client) CreateEnvironmentVariable(ctx context.Context, request CreateEn } payload := string(mustMarshal(request.EnvironmentVariable)) - tflog.Trace(ctx, "creating environment variable", map[string]interface{}{ + tflog.Info(ctx, "creating environment variable", map[string]interface{}{ "url": url, "payload": payload, }) @@ -59,7 +59,7 @@ func (c *Client) CreateEnvironmentVariables(ctx context.Context, request CreateE url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(request.TeamID)) } payload := string(mustMarshal(request.EnvironmentVariables)) - tflog.Trace(ctx, "creating environment variables", map[string]interface{}{ + tflog.Info(ctx, "creating environment variables", map[string]interface{}{ "url": url, "payload": payload, }) diff --git a/client/environment_variable_update.go b/client/environment_variable_update.go index 322a2a6a..bce4908a 100644 --- a/client/environment_variable_update.go +++ b/client/environment_variable_update.go @@ -26,7 +26,7 @@ func (c *Client) UpdateEnvironmentVariable(ctx context.Context, request UpdateEn url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(request.TeamID)) } payload := string(mustMarshal(request)) - tflog.Trace(ctx, "updating environment variable", map[string]interface{}{ + tflog.Info(ctx, "updating environment variable", map[string]interface{}{ "url": url, "payload": payload, }) diff --git a/client/environment_variables_delete.go b/client/environment_variables_delete.go index 4824719a..fe059dbf 100644 --- a/client/environment_variables_delete.go +++ b/client/environment_variables_delete.go @@ -13,7 +13,7 @@ func (c *Client) DeleteEnvironmentVariable(ctx context.Context, projectID, teamI if c.teamID(teamID) != "" { url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(teamID)) } - tflog.Trace(ctx, "deleting environment variable", map[string]interface{}{ + tflog.Info(ctx, "deleting environment variable", map[string]interface{}{ "url": url, }) return c.doRequest(clientRequest{ diff --git a/client/environment_variables_get.go b/client/environment_variables_get.go index 2a206375..6d5c857b 100644 --- a/client/environment_variables_get.go +++ b/client/environment_variables_get.go @@ -16,7 +16,7 @@ func (c *Client) getEnvironmentVariables(ctx context.Context, projectID, teamID envResponse := struct { Env []EnvironmentVariable `json:"envs"` }{} - tflog.Trace(ctx, "getting environment variables", map[string]interface{}{ + tflog.Info(ctx, "getting environment variables", map[string]interface{}{ "url": url, }) err := c.doRequest(clientRequest{ @@ -38,7 +38,7 @@ func (c *Client) GetEnvironmentVariable(ctx context.Context, projectID, teamID, url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(teamID)) } - tflog.Trace(ctx, "getting environment variable", map[string]interface{}{ + tflog.Info(ctx, "getting environment variable", map[string]interface{}{ "url": url, }) err = c.doRequest(clientRequest{ diff --git a/client/error.go b/client/error.go index 688fdcb3..9cad6b4a 100644 --- a/client/error.go +++ b/client/error.go @@ -7,3 +7,8 @@ func NotFound(err error) bool { var apiErr APIError return err != nil && errors.As(err, &apiErr) && apiErr.StatusCode == 404 } + +func noContent(err error) bool { + var apiErr APIError + return err != nil && errors.As(err, &apiErr) && apiErr.StatusCode == 204 +} diff --git a/client/file_create.go b/client/file_create.go index e33e76a7..dcc3254e 100644 --- a/client/file_create.go +++ b/client/file_create.go @@ -36,10 +36,10 @@ func (c *Client) CreateFile(ctx context.Context, request CreateFileRequest) erro req.Header.Add("x-vercel-digest", request.SHA) req.Header.Set("Content-Type", "application/octet-stream") - tflog.Trace(ctx, "uploading file", map[string]interface{}{ + tflog.Info(ctx, "uploading file", map[string]interface{}{ "url": url, "sha": request.SHA, }) - err = c._doRequest(req, nil) + err = c._doRequest(req, nil, false) return err } diff --git a/client/project_create.go b/client/project_create.go index 765c38f3..b0c118cd 100644 --- a/client/project_create.go +++ b/client/project_create.go @@ -50,7 +50,7 @@ func (c *Client) CreateProject(ctx context.Context, teamID string, request Creat } payload := string(mustMarshal(request)) - tflog.Trace(ctx, "creating project", map[string]interface{}{ + tflog.Info(ctx, "creating project", map[string]interface{}{ "url": url, "payload": payload, }) diff --git a/client/project_delete.go b/client/project_delete.go index 0bd772cb..a05ee668 100644 --- a/client/project_delete.go +++ b/client/project_delete.go @@ -14,7 +14,7 @@ func (c *Client) DeleteProject(ctx context.Context, projectID, teamID string) er if c.teamID(teamID) != "" { url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(teamID)) } - tflog.Trace(ctx, "deleting project", map[string]interface{}{ + tflog.Info(ctx, "deleting project", map[string]interface{}{ "url": url, }) return c.doRequest(clientRequest{ diff --git a/client/project_domain_create.go b/client/project_domain_create.go index 67e7ed10..5c584798 100644 --- a/client/project_domain_create.go +++ b/client/project_domain_create.go @@ -26,7 +26,7 @@ func (c *Client) CreateProjectDomain(ctx context.Context, projectID, teamID stri } payload := string(mustMarshal(request)) - tflog.Trace(ctx, "creating project domain", map[string]interface{}{ + tflog.Info(ctx, "creating project domain", map[string]interface{}{ "url": url, "payload": payload, }) diff --git a/client/project_domain_delete.go b/client/project_domain_delete.go index 4a328437..4f86f247 100644 --- a/client/project_domain_delete.go +++ b/client/project_domain_delete.go @@ -14,7 +14,7 @@ func (c *Client) DeleteProjectDomain(ctx context.Context, projectID, domain, tea url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(teamID)) } - tflog.Trace(ctx, "deleting project domain", map[string]interface{}{ + tflog.Info(ctx, "deleting project domain", map[string]interface{}{ "url": url, }) return c.doRequest(clientRequest{ diff --git a/client/project_domain_get.go b/client/project_domain_get.go index d0d8626a..4c3be136 100644 --- a/client/project_domain_get.go +++ b/client/project_domain_get.go @@ -25,7 +25,7 @@ func (c *Client) GetProjectDomain(ctx context.Context, projectID, domain, teamID url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(teamID)) } - tflog.Trace(ctx, "getting project domain", map[string]interface{}{ + tflog.Info(ctx, "getting project domain", map[string]interface{}{ "url": url, }) err = c.doRequest(clientRequest{ diff --git a/client/project_domain_update.go b/client/project_domain_update.go index 84203863..c7022e7f 100644 --- a/client/project_domain_update.go +++ b/client/project_domain_update.go @@ -22,7 +22,7 @@ func (c *Client) UpdateProjectDomain(ctx context.Context, projectID, domain, tea } payload := string(mustMarshal(request)) - tflog.Trace(ctx, "updating project domain", map[string]interface{}{ + tflog.Info(ctx, "updating project domain", map[string]interface{}{ "url": url, "payload": payload, }) diff --git a/client/project_get.go b/client/project_get.go index 6b9e255e..d50e2b22 100644 --- a/client/project_get.go +++ b/client/project_get.go @@ -97,7 +97,7 @@ func (c *Client) GetProject(ctx context.Context, projectID, teamID string, shoul if c.teamID(teamID) != "" { url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(teamID)) } - tflog.Trace(ctx, "getting project", map[string]interface{}{ + tflog.Info(ctx, "getting project", map[string]interface{}{ "url": url, "shouldFetchEnvironment": shouldFetchEnvironmentVariables, }) diff --git a/client/project_list.go b/client/project_list.go index dca8361f..2adfc036 100644 --- a/client/project_list.go +++ b/client/project_list.go @@ -17,7 +17,7 @@ func (c *Client) ListProjects(ctx context.Context, teamID string) (r []ProjectRe pr := struct { Projects []ProjectResponse `json:"projects"` }{} - tflog.Trace(ctx, "listing projects", map[string]interface{}{ + tflog.Info(ctx, "listing projects", map[string]interface{}{ "url": url, }) err = c.doRequest(clientRequest{ diff --git a/client/project_update.go b/client/project_update.go index 7bcea0c7..4e45d95c 100644 --- a/client/project_update.go +++ b/client/project_update.go @@ -37,7 +37,7 @@ func (c *Client) UpdateProject(ctx context.Context, projectID, teamID string, re url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(teamID)) } payload := string(mustMarshal(request)) - tflog.Trace(ctx, "updating project", map[string]interface{}{ + tflog.Info(ctx, "updating project", map[string]interface{}{ "url": url, "payload": payload, "shouldFetchEnvironmentVariables": shouldFetchEnvironmentVariables, diff --git a/client/project_update_production_branch.go b/client/project_update_production_branch.go index 6e8d31ab..a009e765 100644 --- a/client/project_update_production_branch.go +++ b/client/project_update_production_branch.go @@ -19,7 +19,7 @@ func (c *Client) UpdateProductionBranch(ctx context.Context, request UpdateProdu url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(request.TeamID)) } payload := string(mustMarshal(request)) - tflog.Trace(ctx, "updating project production branch", map[string]interface{}{ + tflog.Info(ctx, "updating project production branch", map[string]interface{}{ "url": url, "payload": payload, }) diff --git a/client/request.go b/client/request.go index ed9e238a..675f036f 100644 --- a/client/request.go +++ b/client/request.go @@ -29,10 +29,11 @@ func (e APIError) Error() string { } type clientRequest struct { - ctx context.Context - method string - url string - body string + ctx context.Context + method string + url string + body string + errorOnNoContent bool } func (cr *clientRequest) toHTTPRequest() (*http.Request, error) { @@ -64,7 +65,7 @@ func (c *Client) doRequest(req clientRequest, v interface{}) error { if err != nil { return err } - err = c._doRequest(r, v) + err = c._doRequest(r, v, req.errorOnNoContent) for retries := 0; retries < 3; retries++ { var apiErr APIError if errors.As(err, &apiErr) && // we received an api error @@ -80,7 +81,7 @@ func (c *Client) doRequest(req clientRequest, v interface{}) error { if err != nil { return err } - err = c._doRequest(r, v) + err = c._doRequest(r, v, req.errorOnNoContent) if err != nil { continue } @@ -93,7 +94,7 @@ func (c *Client) doRequest(req clientRequest, v interface{}) error { return err } -func (c *Client) _doRequest(req *http.Request, v interface{}) error { +func (c *Client) _doRequest(req *http.Request, v interface{}, errorOnNoContent bool) error { req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", c.token)) resp, err := c.http().Do(req) if err != nil { @@ -139,9 +140,17 @@ func (c *Client) _doRequest(req *http.Request, v interface{}) error { return nil } + if errorOnNoContent && resp.StatusCode == 204 { + return APIError{ + StatusCode: 204, + Code: "no_content", + Message: "No content", + } + } + err = json.Unmarshal(responseBody, v) if err != nil { - return fmt.Errorf("error unmarshaling response: %w", err) + return fmt.Errorf("error unmarshaling response %s: %w", responseBody, err) } return nil diff --git a/client/shared_environment_variable_create.go b/client/shared_environment_variable_create.go index d480554e..2b678788 100644 --- a/client/shared_environment_variable_create.go +++ b/client/shared_environment_variable_create.go @@ -41,7 +41,7 @@ func (c *Client) CreateSharedEnvironmentVariable(ctx context.Context, request Cr url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(request.TeamID)) } payload := string(mustMarshal(request.EnvironmentVariable)) - tflog.Trace(ctx, "creating shared environment variable", map[string]interface{}{ + tflog.Info(ctx, "creating shared environment variable", map[string]interface{}{ "url": url, "payload": payload, }) diff --git a/client/shared_environment_variable_delete.go b/client/shared_environment_variable_delete.go index 639af7bf..671dc485 100644 --- a/client/shared_environment_variable_delete.go +++ b/client/shared_environment_variable_delete.go @@ -20,7 +20,7 @@ func (c *Client) DeleteSharedEnvironmentVariable(ctx context.Context, teamID, va variableID, }, })) - tflog.Trace(ctx, "deleting shared environment variable", map[string]interface{}{ + tflog.Info(ctx, "deleting shared environment variable", map[string]interface{}{ "url": url, }) return c.doRequest(clientRequest{ diff --git a/client/shared_environment_variable_get.go b/client/shared_environment_variable_get.go index d50645e0..6b7ceaaa 100644 --- a/client/shared_environment_variable_get.go +++ b/client/shared_environment_variable_get.go @@ -13,7 +13,7 @@ func (c *Client) GetSharedEnvironmentVariable(ctx context.Context, teamID, envID url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(teamID)) } - tflog.Trace(ctx, "getting shared environment variable", map[string]interface{}{ + tflog.Info(ctx, "getting shared environment variable", map[string]interface{}{ "url": url, }) err = c.doRequest(clientRequest{ diff --git a/client/shared_environment_variable_list.go b/client/shared_environment_variable_list.go index 984f3a2b..3c99c12f 100644 --- a/client/shared_environment_variable_list.go +++ b/client/shared_environment_variable_list.go @@ -13,7 +13,7 @@ func (c *Client) ListSharedEnvironmentVariables(ctx context.Context, teamID stri url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(teamID)) } - tflog.Trace(ctx, "listing shared environment variables", map[string]interface{}{ + tflog.Info(ctx, "listing shared environment variables", map[string]interface{}{ "url": url, }) res := struct { diff --git a/client/shared_environment_variable_update.go b/client/shared_environment_variable_update.go index 693cf32f..e1f2313a 100644 --- a/client/shared_environment_variable_update.go +++ b/client/shared_environment_variable_update.go @@ -29,7 +29,7 @@ func (c *Client) UpdateSharedEnvironmentVariable(ctx context.Context, request Up }, })) - tflog.Trace(ctx, "updating shared environment variable", map[string]interface{}{ + tflog.Info(ctx, "updating shared environment variable", map[string]interface{}{ "url": url, "payload": payload, }) diff --git a/client/team_create.go b/client/team_create.go index 82f77e3b..b9a63768 100644 --- a/client/team_create.go +++ b/client/team_create.go @@ -23,7 +23,7 @@ func (c *Client) CreateTeam(ctx context.Context, request TeamCreateRequest) (r T url := fmt.Sprintf("%s/v1/teams", c.baseURL) payload := string(mustMarshal(request)) - tflog.Trace(ctx, "creating team", map[string]interface{}{ + tflog.Info(ctx, "creating team", map[string]interface{}{ "url": url, "payload": payload, }) diff --git a/client/team_delete.go b/client/team_delete.go index 871c81a8..f7a1f9b5 100644 --- a/client/team_delete.go +++ b/client/team_delete.go @@ -10,7 +10,7 @@ import ( // DeleteTeam deletes an existing team within vercel. func (c *Client) DeleteTeam(ctx context.Context, teamID string) error { url := fmt.Sprintf("%s/v1/teams/%s", c.baseURL, teamID) - tflog.Trace(ctx, "deleting team", map[string]interface{}{ + tflog.Info(ctx, "deleting team", map[string]interface{}{ "url": url, }) return c.doRequest(clientRequest{ diff --git a/client/team_get.go b/client/team_get.go index bbf5b22c..d169303e 100644 --- a/client/team_get.go +++ b/client/team_get.go @@ -10,7 +10,7 @@ import ( // GetTeam returns information about an existing team within vercel. func (c *Client) GetTeam(ctx context.Context, idOrSlug string) (r TeamResponse, err error) { url := fmt.Sprintf("%s/v2/teams/%s", c.baseURL, idOrSlug) - tflog.Trace(ctx, "getting team", map[string]interface{}{ + tflog.Info(ctx, "getting team", map[string]interface{}{ "url": url, }) err = c.doRequest(clientRequest{ diff --git a/docs/data-sources/edge_config_schema.md b/docs/data-sources/edge_config_schema.md new file mode 100644 index 00000000..4d15aebe --- /dev/null +++ b/docs/data-sources/edge_config_schema.md @@ -0,0 +1,34 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "vercel_edge_config_schema Data Source - terraform-provider-vercel" +subcategory: "" +description: |- + An Edge Config Schema provides an existing Edge Config with a JSON schema. Use schema protection to prevent unexpected updates that may cause bugs or downtime. +--- + +# vercel_edge_config_schema (Data Source) + +An Edge Config Schema provides an existing Edge Config with a JSON schema. Use schema protection to prevent unexpected updates that may cause bugs or downtime. + +## Example Usage + +```terraform +data "vercel_edge_config_schema" "test" { + id = "ecfg_xxxxxxxxxxxxxxxxxxxxxxxxxxxx" +} +``` + + +## Schema + +### Required + +- `id` (String) The ID of the Edge Config that the schema should be for. + +### 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 + +- `definition` (String) A JSON schema that will be used to validate data in the Edge Config. diff --git a/docs/resources/edge_config_schema.md b/docs/resources/edge_config_schema.md new file mode 100644 index 00000000..ceb9bb41 --- /dev/null +++ b/docs/resources/edge_config_schema.md @@ -0,0 +1,63 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "vercel_edge_config_schema Resource - terraform-provider-vercel" +subcategory: "" +description: |- + An Edge Config Schema provides an existing Edge Config with a JSON schema. Use schema protection to prevent unexpected updates that may cause bugs or downtime. +--- + +# vercel_edge_config_schema (Resource) + +An Edge Config Schema provides an existing Edge Config with a JSON schema. Use schema protection to prevent unexpected updates that may cause bugs or downtime. + +## Example Usage + +```terraform +resource "vercel_edge_config" "example" { + name = "example" +} + +resource "vercel_edge_config_schema" "example" { + id = vercel_edge_config.example.id + definition = < +## Schema + +### Required + +- `definition` (String) A JSON schema that will be used to validate data in the Edge Config. +- `id` (String) The ID of the Edge Config that the schema should apply to. + +### 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. + +## 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 can be found by navigating to the Edge Config in the Vercel UI. 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 can be found by navigating to the Edge Config in the Vercel UI. It should begin with `ecfg_`. +terraform import vercel_edge_config.example team_xxxxxxxxxxxxxxxxxxxxxxxx/ecfg_xxxxxxxxxxxxxxxxxxxxxxxxxxxx +``` diff --git a/docs/resources/edge_config_token.md b/docs/resources/edge_config_token.md index fbcaa054..8ccb35c4 100644 --- a/docs/resources/edge_config_token.md +++ b/docs/resources/edge_config_token.md @@ -45,7 +45,7 @@ resource "vercel_project_environment_variable" "example" { ### Required -- `edge_config_id` (String) The label of the Edge Config Token. +- `edge_config_id` (String) The ID of the Edge Config store. - `label` (String) The label of the Edge Config Token. ### Optional diff --git a/examples/data-sources/vercel_edge_config_schema/data-source.tf b/examples/data-sources/vercel_edge_config_schema/data-source.tf new file mode 100644 index 00000000..8bbc908d --- /dev/null +++ b/examples/data-sources/vercel_edge_config_schema/data-source.tf @@ -0,0 +1,3 @@ +data "vercel_edge_config_schema" "test" { + id = "ecfg_xxxxxxxxxxxxxxxxxxxxxxxxxxxx" +} diff --git a/examples/resources/vercel_edge_config_schema/import.sh b/examples/resources/vercel_edge_config_schema/import.sh new file mode 100644 index 00000000..63b58ecf --- /dev/null +++ b/examples/resources/vercel_edge_config_schema/import.sh @@ -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 can be found by navigating to the Edge Config in the Vercel UI. 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 can be found by navigating to the Edge Config in the Vercel UI. It should begin with `ecfg_`. +terraform import vercel_edge_config.example team_xxxxxxxxxxxxxxxxxxxxxxxx/ecfg_xxxxxxxxxxxxxxxxxxxxxxxxxxxx diff --git a/examples/resources/vercel_edge_config_schema/resource.tf b/examples/resources/vercel_edge_config_schema/resource.tf new file mode 100644 index 00000000..a5b8b817 --- /dev/null +++ b/examples/resources/vercel_edge_config_schema/resource.tf @@ -0,0 +1,19 @@ +resource "vercel_edge_config" "example" { + name = "example" +} + +resource "vercel_edge_config_schema" "example" { + id = vercel_edge_config.example.id + definition = <