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

Add support for sensitive environment variable #150

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
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
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ jobs:
- "ubuntu-latest"
- "windows-latest"
terraform:
- "1.6.*"
- "1.0.*"
- "1.7.*"
- "1.4.*"
runs-on: ${{ matrix.os }}
steps:
- name: Set up Go
Expand Down
32 changes: 32 additions & 0 deletions client/shared_environment_variable_list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package client

import (
"context"
"fmt"

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

func (c *Client) ListSharedEnvironmentVariables(ctx context.Context, teamID string) ([]SharedEnvironmentVariableResponse, error) {
url := fmt.Sprintf("%s/v1/env/all", c.baseURL)
if c.teamID(teamID) != "" {
url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(teamID))
}

tflog.Trace(ctx, "listing shared environment variables", map[string]interface{}{
"url": url,
})
res := struct {
Data []SharedEnvironmentVariableResponse `json:"data"`
}{}
err := c.doRequest(clientRequest{
ctx: ctx,
method: "GET",
url: url,
body: "",
}, &res)
for _, v := range res.Data {
v.TeamID = c.teamID(teamID)
}
return res.Data, err
}
1 change: 0 additions & 1 deletion client/shared_environment_variable_update.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
)

type UpdateSharedEnvironmentVariableRequest struct {
Key string `json:"key"`
Value string `json:"value"`
Type string `json:"type"`
ProjectIDs []string `json:"projectId"`
Expand Down
1 change: 1 addition & 0 deletions docs/data-sources/project.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ Read-Only:
- `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.
- `sensitive` (Boolean) Whether the Environment Variable is sensitive or not. Note that the value will be `null` for sensitive environment variables.
- `target` (Set of String) The environments that the environment variable should be present on. Valid targets are either `production`, `preview`, or `development`.
- `value` (String) The value of the environment variable.

Expand Down
1 change: 1 addition & 0 deletions docs/resources/project.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ Required:
Optional:

- `git_branch` (String) The git branch of the Environment Variable.
- `sensitive` (Boolean) Whether the Environment Variable is sensitive or not.

Read-Only:

Expand Down
15 changes: 15 additions & 0 deletions docs/resources/project_environment_variable.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@ resource "vercel_project_environment_variable" "example_git_branch" {
target = ["preview"]
git_branch = "staging"
}

# A sensitive environment variable that will be created
# for this project for the "production" environment.
resource "vercel_project_environment_variable" "example_sensitive" {
project_id = vercel_project.example.id
key = "foo"
value = "bar-production"
target = ["production"]
sensitive = true
}
```

<!-- schema generated by tfplugindocs -->
Expand All @@ -66,6 +76,7 @@ resource "vercel_project_environment_variable" "example_git_branch" {
### Optional

- `git_branch` (String) The git branch of the Environment Variable.
- `sensitive` (Boolean) Whether the Environment Variable is sensitive or not.
- `team_id` (String) The ID of the Vercel team.Required when configuring a team resource if a default team has not been set in the provider.

### Read-Only
Expand All @@ -81,12 +92,16 @@ Import is supported using the following syntax:
# the provider, simply use the project_id and environment variable id.
# - project_id can be found in the project `settings` tab in the Vercel UI.
# - environment variable id is hard to find, but can be taken from the network tab, inside developer tools, on the project page.
#
# Note also, that the value field for sensitive environment variables will be imported as `null`.
terraform import vercel_project_environment_variable.example prj_xxxxxxxxxxxxxxxxxxxxxxxxxxxx/FdT2e1E5Of6Cihmt

# Alternatively, you can import via the team_id, project_id and
# environment variable id.
# - team_id can be found in the team `settings` tab in the Vercel UI.
# - project_id can be found in the project `settings` tab in the Vercel UI.
# - environment variable id is hard to find, but can be taken from the network tab, inside developer tools, on the project page.
#
# Note also, that the value field for sensitive environment variables will be imported as `null`.
terraform import vercel_project_environment_variable.example team_xxxxxxxxxxxxxxxxxxxxxxxx/prj_xxxxxxxxxxxxxxxxxxxxxxxxxxxx/FdT2e1E5Of6Cihmt
```
3 changes: 3 additions & 0 deletions docs/resources/shared_environment_variable.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ resource "vercel_shared_environment_variable" "example" {

### Optional

- `sensitive` (Boolean) Whether the Environment Variable is sensitive or not.
- `team_id` (String) The ID of the Vercel team. Shared environment variables require a team.

### Read-Only
Expand All @@ -66,5 +67,7 @@ Import is supported using the following syntax:
# You can import via the team_id and environment variable id.
# - team_id can be found in the team `settings` tab in the Vercel UI.
# - environment variable id is hard to find, but can be taken from the network tab, inside developer tools, on the shared environment variable page.
#
# Note also, that the value field for sensitive environment variables will be imported as `null`.
terraform import vercel_shared_environment_variable.example team_xxxxxxxxxxxxxxxxxxxxxxxx/env_yyyyyyyyyyyyy
```
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@
# the provider, simply use the project_id and environment variable id.
# - project_id can be found in the project `settings` tab in the Vercel UI.
# - environment variable id is hard to find, but can be taken from the network tab, inside developer tools, on the project page.
#
# Note also, that the value field for sensitive environment variables will be imported as `null`.
terraform import vercel_project_environment_variable.example prj_xxxxxxxxxxxxxxxxxxxxxxxxxxxx/FdT2e1E5Of6Cihmt

# Alternatively, you can import via the team_id, project_id and
# environment variable id.
# - team_id can be found in the team `settings` tab in the Vercel UI.
# - project_id can be found in the project `settings` tab in the Vercel UI.
# - environment variable id is hard to find, but can be taken from the network tab, inside developer tools, on the project page.
#
# Note also, that the value field for sensitive environment variables will be imported as `null`.
terraform import vercel_project_environment_variable.example team_xxxxxxxxxxxxxxxxxxxxxxxx/prj_xxxxxxxxxxxxxxxxxxxxxxxxxxxx/FdT2e1E5Of6Cihmt
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,13 @@ resource "vercel_project_environment_variable" "example_git_branch" {
target = ["preview"]
git_branch = "staging"
}

# A sensitive environment variable that will be created
# for this project for the "production" environment.
resource "vercel_project_environment_variable" "example_sensitive" {
project_id = vercel_project.example.id
key = "foo"
value = "bar-production"
target = ["production"]
sensitive = true
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# You can import via the team_id and environment variable id.
# - team_id can be found in the team `settings` tab in the Vercel UI.
# - environment variable id is hard to find, but can be taken from the network tab, inside developer tools, on the shared environment variable page.
#
# Note also, that the value field for sensitive environment variables will be imported as `null`.
terraform import vercel_shared_environment_variable.example team_xxxxxxxxxxxxxxxxxxxxxxxx/env_yyyyyyyyyyyyy
24 changes: 22 additions & 2 deletions sweep/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,36 @@ func main() {
if err != nil {
panic(err)
}
err = deleteAllProjects(ctx, c, "")
err = deleteAllDNSRecords(ctx, c, domain, teamID)
if err != nil {
panic(err)
}
err = deleteAllDNSRecords(ctx, c, domain, "")
err = deleteAllSharedEnvironmentVariables(ctx, c, teamID)
if err != nil {
panic(err)
}
}

func deleteAllSharedEnvironmentVariables(ctx context.Context, c *client.Client, teamID string) error {
sharedEnvironmentVariables, err := c.ListSharedEnvironmentVariables(ctx, teamID)
if err != nil {
return fmt.Errorf("error listing shared environment variables: %w", err)
}
for _, d := range sharedEnvironmentVariables {
if !strings.HasPrefix(d.Key, "test_acc") {
// Don't delete actual shared environment variables - only testing ones
continue
}

err = c.DeleteSharedEnvironmentVariable(ctx, teamID, d.ID)
if err != nil {
return fmt.Errorf("error deleting shared env var %s: %w", d.Key, err)
}
}

return nil
}

func deleteAllDNSRecords(ctx context.Context, c *client.Client, domain, teamID string) error {
dnsRecords, err := c.ListDNSRecords(ctx, domain, teamID)
if err != nil {
Expand Down
10 changes: 10 additions & 0 deletions vercel/contains.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package vercel

func contains(items []string, i string) bool {
for _, j := range items {
if j == i {
return true
}
}
return false
}
13 changes: 12 additions & 1 deletion vercel/data_source_project.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ For more detailed information, please see the [Vercel documentation](https://ver
Description: "The git branch of the environment variable.",
Computed: true,
},
"sensitive": schema.BoolAttribute{
Description: "Whether the Environment Variable is sensitive or not. Note that the value will be `null` for sensitive environment variables.",
Computed: true,
},
},
},
},
Expand Down Expand Up @@ -237,7 +241,14 @@ func (d *projectDataSource) Read(ctx context.Context, req datasource.ReadRequest
return
}

result := convertResponseToProjectDataSource(out, nullProject)
result, err := convertResponseToProjectDataSource(ctx, out, nullProject)
if err != nil {
resp.Diagnostics.AddError(
"Error converting project response to model",
"Could not create project, unexpected error: "+err.Error(),
)
return
}
tflog.Trace(ctx, "read project", map[string]interface{}{
"team_id": result.TeamID.ValueString(),
"project_id": result.ID.ValueString(),
Expand Down
11 changes: 8 additions & 3 deletions vercel/data_source_project_model.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package vercel

import (
"context"

"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/vercel/terraform-provider-vercel/client"
)
Expand All @@ -26,8 +28,11 @@ type ProjectDataSource struct {
TrustedIps *TrustedIps `tfsdk:"trusted_ips"`
}

func convertResponseToProjectDataSource(response client.ProjectResponse, plan Project) ProjectDataSource {
project := convertResponseToProject(response, plan)
func convertResponseToProjectDataSource(ctx context.Context, response client.ProjectResponse, plan Project) (ProjectDataSource, error) {
project, err := convertResponseToProject(ctx, response, plan)
if err != nil {
return ProjectDataSource{}, err
}

var pp *PasswordProtection
if project.PasswordProtection != nil {
Expand All @@ -53,5 +58,5 @@ func convertResponseToProjectDataSource(response client.ProjectResponse, plan Pr
VercelAuthentication: project.VercelAuthentication,
PasswordProtection: pp,
TrustedIps: project.TrustedIps,
}
}, nil
}
59 changes: 53 additions & 6 deletions vercel/resource_project.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,11 @@ At this time you cannot use a Vercel Project resource with in-line ` + "`environ
Description: "The ID of the Environment Variable.",
Computed: true,
},
"sensitive": schema.BoolAttribute{
Description: "Whether the Environment Variable is sensitive or not.",
Optional: true,
Computed: true,
},
},
},
},
Expand Down Expand Up @@ -325,7 +330,14 @@ func (r *projectResource) Create(ctx context.Context, req resource.CreateRequest
return
}

result := convertResponseToProject(out, plan)
result, err := convertResponseToProject(ctx, out, plan)
if err != nil {
resp.Diagnostics.AddError(
"Error converting project response to model",
"Could not create project, unexpected error: "+err.Error(),
)
return
}
tflog.Trace(ctx, "created project", map[string]interface{}{
"team_id": result.TeamID.ValueString(),
"project_id": result.ID.ValueString(),
Expand All @@ -346,7 +358,14 @@ func (r *projectResource) Create(ctx context.Context, req resource.CreateRequest
return
}

result = convertResponseToProject(out, plan)
result, err = convertResponseToProject(ctx, out, plan)
if err != nil {
resp.Diagnostics.AddError(
"Error converting project response to model",
"Could not create project, unexpected error: "+err.Error(),
)
return
}
tflog.Trace(ctx, "updated newly created project", map[string]interface{}{
"team_id": result.TeamID.ValueString(),
"project_id": result.ID.ValueString(),
Expand Down Expand Up @@ -397,7 +416,14 @@ func (r *projectResource) Create(ctx context.Context, req resource.CreateRequest
return
}

result = convertResponseToProject(out, plan)
result, err = convertResponseToProject(ctx, out, plan)
if err != nil {
resp.Diagnostics.AddError(
"Error converting project response to model",
"Could not create project, unexpected error: "+err.Error(),
)
return
}
tflog.Trace(ctx, "updated project production branch", map[string]interface{}{
"team_id": result.TeamID.ValueString(),
"project_id": result.ID.ValueString(),
Expand Down Expand Up @@ -437,7 +463,14 @@ func (r *projectResource) Read(ctx context.Context, req resource.ReadRequest, re
return
}

result := convertResponseToProject(out, state)
result, err := convertResponseToProject(ctx, out, state)
if err != nil {
resp.Diagnostics.AddError(
"Error converting project response to model",
"Could not create project, unexpected error: "+err.Error(),
)
return
}
tflog.Trace(ctx, "read project", map[string]interface{}{
"team_id": result.TeamID.ValueString(),
"project_id": result.ID.ValueString(),
Expand Down Expand Up @@ -629,7 +662,14 @@ func (r *projectResource) Update(ctx context.Context, req resource.UpdateRequest
}
}

result := convertResponseToProject(out, plan)
result, err := convertResponseToProject(ctx, out, plan)
if err != nil {
resp.Diagnostics.AddError(
"Error converting project response to model",
"Could not create project, unexpected error: "+err.Error(),
)
return
}
tflog.Trace(ctx, "updated project", map[string]interface{}{
"team_id": result.TeamID.ValueString(),
"project_id": result.ID.ValueString(),
Expand Down Expand Up @@ -712,7 +752,14 @@ func (r *projectResource) ImportState(ctx context.Context, req resource.ImportSt
return
}

result := convertResponseToProject(out, nullProject)
result, err := convertResponseToProject(ctx, out, nullProject)
if err != nil {
resp.Diagnostics.AddError(
"Error converting project response to model",
"Could not create project, unexpected error: "+err.Error(),
)
return
}
tflog.Trace(ctx, "imported project", map[string]interface{}{
"team_id": result.TeamID.ValueString(),
"project_id": result.ID.ValueString(),
Expand Down
Loading