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

Add support for custom enviroments #246

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 9 commits into from
Dec 19, 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
138 changes: 138 additions & 0 deletions client/custom_environment.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package client

import (
"context"
"fmt"

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

type BranchMatcher struct {
Pattern string `json:"pattern"`
Type string `json:"type"`
}

type CreateCustomEnvironmentRequest struct {
TeamID string `json:"-"`
ProjectID string `json:"-"`
Slug string `json:"slug"`
Description string `json:"description"`
BranchMatcher *BranchMatcher `json:"branchMatcher,omitempty"`
}

type CustomEnvironmentResponse struct {
ID string `json:"id"`
Description string `json:"description"`
Slug string `json:"slug"`
BranchMatcher *BranchMatcher `json:"branchMatcher"`
TeamID string `json:"-"`
ProjectID string `json:"-"`
}

func (c *Client) CreateCustomEnvironment(ctx context.Context, request CreateCustomEnvironmentRequest) (res CustomEnvironmentResponse, err error) {
url := fmt.Sprintf("%s/v1/projects/%s/custom-environments", c.baseURL, request.ProjectID)
if c.teamID(request.TeamID) != "" {
url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(request.TeamID))
}
payload := string(mustMarshal(request))
tflog.Info(ctx, "creating custom environment", map[string]interface{}{
"url": url,
"payload": payload,
})
err = c.doRequest(clientRequest{
ctx: ctx,
method: "POST",
url: url,
body: payload,
}, &res)
if err != nil {
return res, err
}
res.TeamID = c.teamID(request.TeamID)
res.ProjectID = request.ProjectID
return res, nil
}

type GetCustomEnvironmentRequest struct {
TeamID string `json:"-"`
ProjectID string `json:"-"`
Slug string `json:"-"`
}

func (c *Client) GetCustomEnvironment(ctx context.Context, request GetCustomEnvironmentRequest) (res CustomEnvironmentResponse, err error) {
url := fmt.Sprintf("%s/v1/projects/%s/custom-environments/%s", c.baseURL, request.ProjectID, request.Slug)
if c.teamID(request.TeamID) != "" {
url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(request.TeamID))
}
tflog.Info(ctx, "getting custom environment", map[string]interface{}{
"url": url,
})
err = c.doRequest(clientRequest{
ctx: ctx,
method: "GET",
url: url,
}, &res)
if err != nil {
return res, err
}
res.TeamID = c.teamID(request.TeamID)
res.ProjectID = request.ProjectID
return res, nil

}

type UpdateCustomEnvironmentRequest struct {
TeamID string `json:"-"`
ProjectID string `json:"-"`
OldSlug string `json:"-"` // Needed to get the right URL
Slug string `json:"slug"`
Description string `json:"description"`
BranchMatcher *BranchMatcher `json:"branchMatcher"`
}

func (c *Client) UpdateCustomEnvironment(ctx context.Context, request UpdateCustomEnvironmentRequest) (res CustomEnvironmentResponse, err error) {
url := fmt.Sprintf("%s/v1/projects/%s/custom-environments/%s", c.baseURL, request.ProjectID, request.OldSlug)
if c.teamID(request.TeamID) != "" {
url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(request.TeamID))
}
payload := string(mustMarshal(request))
tflog.Info(ctx, "updating custom environment", map[string]interface{}{
"url": url,
"payload": payload,
})
err = c.doRequest(clientRequest{
ctx: ctx,
method: "PATCH",
url: url,
body: payload,
}, &res)
if err != nil {
return res, err
}
res.TeamID = c.teamID(request.TeamID)
res.ProjectID = request.ProjectID
return res, nil
}

type DeleteCustomEnvironmentRequest struct {
TeamID string `json:"-"`
ProjectID string `json:"-"`
Slug string `json:"-"`
}

func (c *Client) DeleteCustomEnvironment(ctx context.Context, request DeleteCustomEnvironmentRequest) error {
url := fmt.Sprintf("%s/v1/projects/%s/custom-environments/%s", c.baseURL, request.ProjectID, request.Slug)
if c.teamID(request.TeamID) != "" {
url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(request.TeamID))
}
tflog.Info(ctx, "deleting custom environment", map[string]interface{}{
"url": url,
})
err := c.doRequest(clientRequest{
ctx: ctx,
method: "DELETE",
url: url,
body: "{ \"deleteUnassignedEnvironmentVariables\": true }",
}, nil)
return err
}
42 changes: 26 additions & 16 deletions client/environment_variable.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ import (
// CreateEnvironmentVariableRequest defines the information that needs to be passed to Vercel in order to
// create an environment variable.
type EnvironmentVariableRequest struct {
Key string `json:"key"`
Value string `json:"value"`
Target []string `json:"target"`
GitBranch *string `json:"gitBranch,omitempty"`
Type string `json:"type"`
Comment string `json:"comment"`
Key string `json:"key"`
Value string `json:"value"`
Target []string `json:"target,omitempty"`
CustomEnvironmentIDs []string `json:"customEnvironmentIds,omitempty"`
GitBranch *string `json:"gitBranch,omitempty"`
Type string `json:"type"`
Comment string `json:"comment"`
}

type CreateEnvironmentVariableRequest struct {
Expand Down Expand Up @@ -58,7 +59,7 @@ func (c *Client) CreateEnvironmentVariable(ctx context.Context, request CreateEn
}
}
if err != nil {
return e, err
return e, fmt.Errorf("%w - %s", err, payload)
}
// The API response returns an encrypted environment variable, but we want to return the decrypted version.
e.Value = request.EnvironmentVariable.Value
Expand Down Expand Up @@ -127,6 +128,14 @@ type CreateEnvironmentVariablesResponse struct {
}

func (c *Client) CreateEnvironmentVariables(ctx context.Context, request CreateEnvironmentVariablesRequest) ([]EnvironmentVariable, error) {
if len(request.EnvironmentVariables) == 1 {
env, err := c.CreateEnvironmentVariable(ctx, CreateEnvironmentVariableRequest{
EnvironmentVariable: request.EnvironmentVariables[0],
ProjectID: request.ProjectID,
TeamID: request.TeamID,
})
return []EnvironmentVariable{env}, err
}
url := fmt.Sprintf("%s/v10/projects/%s/env", c.baseURL, request.ProjectID)
if c.teamID(request.TeamID) != "" {
url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(request.TeamID))
Expand All @@ -145,7 +154,7 @@ func (c *Client) CreateEnvironmentVariables(ctx context.Context, request CreateE
body: payload,
}, &response)
if err != nil {
return nil, err
return nil, fmt.Errorf("%w - %s", err, payload)
}

if len(response.Failed) > 0 {
Expand Down Expand Up @@ -176,14 +185,15 @@ func (c *Client) CreateEnvironmentVariables(ctx context.Context, request CreateE
// UpdateEnvironmentVariableRequest defines the information that needs to be passed to Vercel in order to
// update an environment variable.
type UpdateEnvironmentVariableRequest struct {
Value string `json:"value"`
Target []string `json:"target"`
GitBranch *string `json:"gitBranch,omitempty"`
Type string `json:"type"`
Comment string `json:"comment"`
ProjectID string `json:"-"`
TeamID string `json:"-"`
EnvID string `json:"-"`
Value string `json:"value"`
Target []string `json:"target"`
CustomEnvironmentIDs []string `json:"customEnvironmentIds,omitempty"`
GitBranch *string `json:"gitBranch,omitempty"`
Type string `json:"type"`
Comment string `json:"comment"`
ProjectID string `json:"-"`
TeamID string `json:"-"`
EnvID string `json:"-"`
}

// UpdateEnvironmentVariable will update an existing environment variable to the latest information.
Expand Down
21 changes: 11 additions & 10 deletions client/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,16 @@ type OIDCTokenConfig struct {
// EnvironmentVariable defines the information Vercel requires and surfaces about an environment variable
// that is associated with a project.
type EnvironmentVariable struct {
Key string `json:"key"`
Value string `json:"value"`
Target []string `json:"target"`
GitBranch *string `json:"gitBranch,omitempty"`
Type string `json:"type"`
ID string `json:"id,omitempty"`
TeamID string `json:"-"`
Comment string `json:"comment"`
Decrypted bool `json:"decrypted"`
Key string `json:"key"`
Value string `json:"value"`
Target []string `json:"target"`
CustomEnvironmentIDs []string `json:"customEnvironmentIds"`
GitBranch *string `json:"gitBranch,omitempty"`
Type string `json:"type"`
ID string `json:"id,omitempty"`
TeamID string `json:"-"`
Comment string `json:"comment"`
Decrypted bool `json:"decrypted"`
}

type DeploymentExpiration struct {
Expand All @@ -46,7 +47,7 @@ type CreateProjectRequest struct {
BuildCommand *string `json:"buildCommand"`
CommandForIgnoringBuildStep *string `json:"commandForIgnoringBuildStep,omitempty"`
DevCommand *string `json:"devCommand"`
EnvironmentVariables []EnvironmentVariable `json:"environmentVariables"`
EnvironmentVariables []EnvironmentVariable `json:"environmentVariables,omitempty"`
Framework *string `json:"framework"`
GitRepository *GitRepository `json:"gitRepository,omitempty"`
InstallCommand *string `json:"installCommand"`
Expand Down
29 changes: 16 additions & 13 deletions client/project_domain.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ import (
// used to assign a domain name to any production deployments, but can also be used to configure
// redirects, or to give specific git branches a domain name.
type CreateProjectDomainRequest struct {
Name string `json:"name"`
GitBranch string `json:"gitBranch,omitempty"`
Redirect string `json:"redirect,omitempty"`
RedirectStatusCode int64 `json:"redirectStatusCode,omitempty"`
Name string `json:"name"`
GitBranch string `json:"gitBranch,omitempty"`
CustomEnvironmentID string `json:"customEnvironmentId,omitempty"`
Redirect string `json:"redirect,omitempty"`
RedirectStatusCode int64 `json:"redirectStatusCode,omitempty"`
}

// CreateProjectDomain creates a project domain within Vercel.
Expand Down Expand Up @@ -61,12 +62,13 @@ func (c *Client) DeleteProjectDomain(ctx context.Context, projectID, domain, tea
// ProjectDomainResponse defines the information that Vercel exposes about a domain that is
// associated with a vercel project.
type ProjectDomainResponse struct {
Name string `json:"name"`
ProjectID string `json:"projectId"`
TeamID string `json:"-"`
Redirect *string `json:"redirect"`
RedirectStatusCode *int64 `json:"redirectStatusCode"`
GitBranch *string `json:"gitBranch"`
Name string `json:"name"`
ProjectID string `json:"projectId"`
TeamID string `json:"-"`
Redirect *string `json:"redirect"`
RedirectStatusCode *int64 `json:"redirectStatusCode"`
GitBranch *string `json:"gitBranch"`
CustomEnvironmentID *string `json:"customEnvironmentId"`
}

// GetProjectDomain retrieves information about a project domain from Vercel.
Expand All @@ -91,9 +93,10 @@ func (c *Client) GetProjectDomain(ctx context.Context, projectID, domain, teamID

// UpdateProjectDomainRequest defines the information necessary to update a project domain.
type UpdateProjectDomainRequest struct {
GitBranch *string `json:"gitBranch"`
Redirect *string `json:"redirect"`
RedirectStatusCode *int64 `json:"redirectStatusCode"`
GitBranch *string `json:"gitBranch"`
CustomEnvironmentID *string `json:"customEnvironmentId,omitempty"`
Redirect *string `json:"redirect"`
RedirectStatusCode *int64 `json:"redirectStatusCode"`
}

// UpdateProjectDomain updates an existing project domain within Vercel.
Expand Down
5 changes: 4 additions & 1 deletion client/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,11 @@ func (c *Client) _doRequest(req *http.Request, v interface{}, errorOnNoContent b
}{
Error: &errorResponse,
})
if errorResponse.Code == "" && errorResponse.Message == "" {
return fmt.Errorf("error performing API request: %d %s", resp.StatusCode, string(responseBody))
}
if err != nil {
return fmt.Errorf("error unmarshaling response for status code %d: %w", resp.StatusCode, err)
return fmt.Errorf("error unmarshaling response for status code %d: %w: %s", resp.StatusCode, err, string(responseBody))
}
errorResponse.StatusCode = resp.StatusCode
errorResponse.RawMessage = responseBody
Expand Down
53 changes: 53 additions & 0 deletions docs/data-sources/custom_environment.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_custom_environment Data Source - terraform-provider-vercel"
subcategory: ""
description: |-
Provides information about an existing CustomEnvironment resource.
An CustomEnvironment allows a vercel_deployment to be accessed through a different URL.
---

# vercel_custom_environment (Data Source)

Provides information about an existing CustomEnvironment resource.

An CustomEnvironment allows a `vercel_deployment` to be accessed through a different URL.

## Example Usage

```terraform
data "vercel_project" "example" {
name = "example-project-with-custom-env"
}

data "vercel_custom_environment" "example" {
project_id = data.vercel_project.example.id
name = "example-custom-env"
}
```

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

### Required

- `name` (String) The name of the environment.
- `project_id` (String) The ID of the existing Vercel Project.

### Optional

- `team_id` (String) The team ID to add the project to. Required when configuring a team resource if a default team has not been set in the provider.

### Read-Only

- `branch_tracking` (Attributes) The branch tracking configuration for the environment. When enabled, each qualifying merge will generate a deployment. (see [below for nested schema](#nestedatt--branch_tracking))
- `description` (String) A description of what the environment is.
- `id` (String) The ID of the environment.

<a id="nestedatt--branch_tracking"></a>
### Nested Schema for `branch_tracking`

Read-Only:

- `pattern` (String) The pattern of the branch name to track.
- `type` (String) How a branch name should be matched against the pattern. Must be one of 'startsWith', 'endsWith' or 'equals'.
1 change: 1 addition & 0 deletions docs/data-sources/project.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ data "vercel_project" "example" {
Read-Only:

- `comment` (String) A comment explaining what the environment variable is for.
- `custom_environment_ids` (Set of String) The IDs of Custom Environments that the Environment Variable should be present on.
- `git_branch` (String) The git branch of the environment variable.
- `id` (String) The ID of the environment variable
- `key` (String) The name of the environment variable.
Expand Down
Loading
Loading