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

Add support for Vercel Authentication + Password Protection #113

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 5 commits into from
May 17, 2023
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
2 changes: 1 addition & 1 deletion client/environment_variable_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func (c *Client) CreateEnvironmentVariables(ctx context.Context, request CreateE
return err
}

tflog.Trace(ctx, "creating environment variable", map[string]interface{}{
tflog.Trace(ctx, "creating environment variables", map[string]interface{}{
"url": url,
"payload": payload,
})
Expand Down
16 changes: 11 additions & 5 deletions client/project_get.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ func (r *ProjectResponse) Repository() *Repository {
return nil
}

type Protection struct {
DeploymentType string `json:"deploymentType"`
}

// ProjectResponse defines the information Vercel returns about a project.
type ProjectResponse struct {
BuildCommand *string `json:"buildCommand"`
Expand All @@ -80,11 +84,13 @@ type ProjectResponse struct {
// production branch
ProductionBranch *string `json:"productionBranch"`
} `json:"link"`
Name string `json:"name"`
OutputDirectory *string `json:"outputDirectory"`
PublicSource *bool `json:"publicSource"`
RootDirectory *string `json:"rootDirectory"`
ServerlessFunctionRegion *string `json:"serverlessFunctionRegion"`
Name string `json:"name"`
OutputDirectory *string `json:"outputDirectory"`
PublicSource *bool `json:"publicSource"`
RootDirectory *string `json:"rootDirectory"`
ServerlessFunctionRegion *string `json:"serverlessFunctionRegion"`
SSOProtection *Protection `json:"ssoProtection"`
PasswordProtection *Protection `json:"passwordProtection"`
}

// GetProject retrieves information about an existing project from Vercel.
Expand Down
29 changes: 18 additions & 11 deletions client/project_update.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,30 @@ import (
"github.com/hashicorp/terraform-plugin-log/tflog"
)

type PasswordProtectionRequest struct {
DeploymentType string `json:"deploymentType"`
Password string `json:"password"`
}

// UpdateProjectRequest defines the possible fields that can be updated within a vercel project.
// note that the values are all pointers, with many containing `omitempty` for serialisation.
// This is because the Vercel API behaves in the following manner:
// - a provided field will be updated
// - setting the field to an empty value (e.g. ) will remove the setting for that field.
// - setting the field to an empty value (e.g. "") will remove the setting for that field.
// - omitting the value entirely from the request will _not_ update the field.
type UpdateProjectRequest struct {
BuildCommand *string `json:"buildCommand"`
CommandForIgnoringBuildStep *string `json:"commandForIgnoringBuildStep"`
DevCommand *string `json:"devCommand"`
Framework *string `json:"framework"`
InstallCommand *string `json:"installCommand"`
Name *string `json:"name,omitempty"`
OutputDirectory *string `json:"outputDirectory"`
PublicSource *bool `json:"publicSource"`
RootDirectory *string `json:"rootDirectory"`
ServerlessFunctionRegion *string `json:"serverlessFunctionRegion"`
BuildCommand *string `json:"buildCommand"`
CommandForIgnoringBuildStep *string `json:"commandForIgnoringBuildStep"`
DevCommand *string `json:"devCommand"`
Framework *string `json:"framework"`
InstallCommand *string `json:"installCommand"`
Name *string `json:"name,omitempty"`
OutputDirectory *string `json:"outputDirectory"`
PublicSource *bool `json:"publicSource"`
RootDirectory *string `json:"rootDirectory"`
ServerlessFunctionRegion *string `json:"serverlessFunctionRegion"`
SSOProtection *Protection `json:"ssoProtection"`
PasswordProtection *PasswordProtectionRequest `json:"passwordProtection"`
}

// UpdateProject updates an existing projects configuration within Vercel.
Expand Down
18 changes: 18 additions & 0 deletions docs/data-sources/project.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ output "project_id" {

### Optional

- `password_protection` (Attributes) Ensures visitors of your Preview Deployments must enter a password in order to gain access. (see [below for nested schema](#nestedatt--password_protection))
- `team_id` (String) The team ID the project exists beneath.

### Read-Only
Expand All @@ -54,6 +55,15 @@ output "project_id" {
- `public_source` (Boolean) Specifies whether the source code and logs of the deployments for this project should be public or not.
- `root_directory` (String) The name of a directory or relative path to the source code of your project. When null is used it will default to the project root.
- `serverless_function_region` (String) The region on Vercel's network to which your Serverless Functions are deployed. It should be close to any data source your Serverless Function might depend on. A new Deployment is required for your changes to take effect. Please see [Vercel's documentation](https://vercel.com/docs/concepts/edge-network/regions) for a full list of regions.
- `vercel_authentication` (Attributes) Ensures visitors to your Preview Deployments are logged into Vercel and have a minimum of Viewer access on your team. (see [below for nested schema](#nestedatt--vercel_authentication))

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

Read-Only:

- `protect_production` (Boolean) If true, production deployments will also be protected


<a id="nestedatt--environment"></a>
### Nested Schema for `environment`
Expand All @@ -77,3 +87,11 @@ Read-Only:
- `type` (String) The git provider of the repository. Must be either `github`, `gitlab`, or `bitbucket`.


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

Read-Only:

- `protect_production` (Boolean) If true, production deployments will also be protected


22 changes: 22 additions & 0 deletions docs/resources/project.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,12 @@ resource "vercel_project" "example" {
- `ignore_command` (String) When a commit is pushed to the Git repository that is connected with your Project, its SHA will determine if a new Build has to be issued. If the SHA was deployed before, no new Build will be issued. You can customize this behavior with a command that exits with code 1 (new Build needed) or code 0.
- `install_command` (String) The install command for this project. If omitted, this value will be automatically detected.
- `output_directory` (String) The output directory of the project. If omitted, this value will be automatically detected.
- `password_protection` (Attributes) Ensures visitors of your Preview Deployments must enter a password in order to gain access. (see [below for nested schema](#nestedatt--password_protection))
- `public_source` (Boolean) By default, visitors to the `/_logs` and `/_src` paths of your Production and Preview Deployments must log in with Vercel (requires being a member of your team) to see the Source, Logs and Deployment Status of your project. Setting `public_source` to `true` disables this behaviour, meaning the Source, Logs and Deployment Status can be publicly viewed.
- `root_directory` (String) The name of a directory or relative path to the source code of your project. If omitted, it will default to the project root.
- `serverless_function_region` (String) The region on Vercel's network to which your Serverless Functions are deployed. It should be close to any data source your Serverless Function might depend on. A new Deployment is required for your changes to take effect. Please see [Vercel's documentation](https://vercel.com/docs/concepts/edge-network/regions) for a full list of regions.
- `team_id` (String) The team ID to add the project to.
- `vercel_authentication` (Attributes) Ensures visitors to your Preview Deployments are logged into Vercel and have a minimum of Viewer access on your team. (see [below for nested schema](#nestedatt--vercel_authentication))

### Read-Only

Expand Down Expand Up @@ -102,6 +104,26 @@ Optional:

- `production_branch` (String) By default, every commit pushed to the main branch will trigger a Production Deployment instead of the usual Preview Deployment. You can switch to a different branch here.


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

Required:

- `password` (String, Sensitive) The password that visitors must enter to gain access to your Preview Deployments. Drift detection is not possible for this field.

Optional:

- `protect_production` (Boolean) If true, production deployments will also be protected


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

Optional:

- `protect_production` (Boolean) If true, production deployments will also be protected

## Import

Import is supported using the following syntax:
Expand Down
5 changes: 5 additions & 0 deletions vercel/data_source_alias.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ import (
"github.com/vercel/terraform-provider-vercel/client"
)

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

func newAliasDataSource() datasource.DataSource {
return &aliasDataSource{}
}
Expand Down
5 changes: 5 additions & 0 deletions vercel/data_source_file.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ import (
"github.com/vercel/terraform-provider-vercel/client"
)

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

func newFileDataSource() datasource.DataSource {
return &fileDataSource{}
}
Expand Down
5 changes: 5 additions & 0 deletions vercel/data_source_prebuilt_project.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ import (
"github.com/vercel/terraform-provider-vercel/file"
)

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

func newPrebuiltProjectDataSource() datasource.DataSource {
return &prebuiltProjectDataSource{}
}
Expand Down
29 changes: 27 additions & 2 deletions vercel/data_source_project.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ import (
"github.com/vercel/terraform-provider-vercel/client"
)

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

func newProjectDataSource() datasource.DataSource {
return &projectDataSource{}
}
Expand Down Expand Up @@ -140,6 +145,26 @@ For more detailed information, please see the [Vercel documentation](https://ver
},
},
},
"vercel_authentication": schema.SingleNestedAttribute{
Description: "Ensures visitors to your Preview Deployments are logged into Vercel and have a minimum of Viewer access on your team.",
Computed: true,
Attributes: map[string]schema.Attribute{
"protect_production": schema.BoolAttribute{
Description: "If true, production deployments will also be protected",
Computed: true,
},
},
},
"password_protection": schema.SingleNestedAttribute{
Description: "Ensures visitors of your Preview Deployments must enter a password in order to gain access.",
Optional: true,
Attributes: map[string]schema.Attribute{
"protect_production": schema.BoolAttribute{
Description: "If true, production deployments will also be protected",
Computed: true,
},
},
},
"id": schema.StringAttribute{
Computed: true,
},
Expand Down Expand Up @@ -167,7 +192,7 @@ For more detailed information, please see the [Vercel documentation](https://ver
// with this information.
// It is called by the provider whenever data source values should be read to update state.
func (d *projectDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var config Project
var config ProjectDataSource
diags := req.Config.Get(ctx, &config)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
Expand All @@ -187,7 +212,7 @@ func (d *projectDataSource) Read(ctx context.Context, req datasource.ReadRequest
return
}

result := convertResponseToProject(out, config.coercedFields(), types.SetNull(envVariableElemType))
result := convertResponseToProjectDataSource(out, nullProject)
tflog.Trace(ctx, "read project", map[string]interface{}{
"team_id": result.TeamID.ValueString(),
"project_id": result.ID.ValueString(),
Expand Down
5 changes: 5 additions & 0 deletions vercel/data_source_project_directory.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ import (
"github.com/vercel/terraform-provider-vercel/file"
)

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

func newProjectDirectoryDataSource() datasource.DataSource {
return &projectDirectoryDataSource{}
}
Expand Down
59 changes: 59 additions & 0 deletions vercel/data_source_project_model.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package vercel

import (
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/vercel/terraform-provider-vercel/client"
)

// Project reflects the state terraform stores internally for a project.
type ProjectDataSource struct {
BuildCommand types.String `tfsdk:"build_command"`
DevCommand types.String `tfsdk:"dev_command"`
Environment types.Set `tfsdk:"environment"`
Framework types.String `tfsdk:"framework"`
GitRepository *GitRepository `tfsdk:"git_repository"`
ID types.String `tfsdk:"id"`
IgnoreCommand types.String `tfsdk:"ignore_command"`
InstallCommand types.String `tfsdk:"install_command"`
Name types.String `tfsdk:"name"`
OutputDirectory types.String `tfsdk:"output_directory"`
PublicSource types.Bool `tfsdk:"public_source"`
RootDirectory types.String `tfsdk:"root_directory"`
ServerlessFunctionRegion types.String `tfsdk:"serverless_function_region"`
TeamID types.String `tfsdk:"team_id"`
VercelAuthentication *VercelAuthentication `tfsdk:"vercel_authentication"`
PasswordProtection *PasswordProtectionDataSource `tfsdk:"password_protection"`
}

type PasswordProtectionDataSource struct {
ProtectProduction types.Bool `tfsdk:"protect_production"`
}

func convertResponseToProjectDataSource(response client.ProjectResponse, plan Project) ProjectDataSource {
project := convertResponseToProject(response, plan)

var pp *PasswordProtectionDataSource
if project.PasswordProtection != nil {
pp = &PasswordProtectionDataSource{
ProtectProduction: project.PasswordProtection.ProtectProduction,
}
}
return ProjectDataSource{
BuildCommand: project.BuildCommand,
DevCommand: project.DevCommand,
Environment: project.Environment,
Framework: project.Framework,
GitRepository: project.GitRepository,
ID: project.ID,
IgnoreCommand: project.IgnoreCommand,
InstallCommand: project.InstallCommand,
Name: project.Name,
OutputDirectory: project.OutputDirectory,
PublicSource: project.PublicSource,
RootDirectory: project.RootDirectory,
ServerlessFunctionRegion: project.ServerlessFunctionRegion,
TeamID: project.TeamID,
VercelAuthentication: project.VercelAuthentication,
PasswordProtection: pp,
}
}
9 changes: 9 additions & 0 deletions vercel/data_source_project_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ func TestAcc_ProjectDataSource(t *testing.T) {
resource.TestCheckResourceAttr("data.vercel_project.test", "output_directory", ".output"),
resource.TestCheckResourceAttr("data.vercel_project.test", "public_source", "true"),
resource.TestCheckResourceAttr("data.vercel_project.test", "root_directory", "ui/src"),
resource.TestCheckResourceAttr("data.vercel_project.test", "vercel_authentication.protect_production", "true"),
resource.TestCheckResourceAttr("data.vercel_project.test", "password_protection.protect_production", "true"),
resource.TestCheckTypeSetElemNestedAttrs("data.vercel_project.test", "environment.*", map[string]string{
"key": "foo",
"value": "bar",
Expand All @@ -47,6 +49,13 @@ resource "vercel_project" "test" {
output_directory = ".output"
public_source = true
root_directory = "ui/src"
vercel_authentication = {
protect_production = true
}
password_protection = {
password = "foo"
protect_production = true
}
%s
environment = [
{
Expand Down
6 changes: 6 additions & 0 deletions vercel/resource_alias.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ import (
"github.com/vercel/terraform-provider-vercel/client"
)

// Ensure the implementation satisfies the expected interfaces.
var (
_ resource.Resource = &aliasResource{}
_ resource.ResourceWithConfigure = &aliasResource{}
)

func newAliasResource() resource.Resource {
return &aliasResource{}
}
Expand Down
5 changes: 5 additions & 0 deletions vercel/resource_deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ import (
"github.com/vercel/terraform-provider-vercel/file"
)

var (
_ resource.Resource = &deploymentResource{}
_ resource.ResourceWithConfigure = &deploymentResource{}
)

func newDeploymentResource() resource.Resource {
return &deploymentResource{}
}
Expand Down
5 changes: 5 additions & 0 deletions vercel/resource_dns_record.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ import (
"github.com/vercel/terraform-provider-vercel/client"
)

var (
_ resource.Resource = &dnsRecordResource{}
_ resource.ResourceWithConfigure = &dnsRecordResource{}
)

func newDNSRecordResource() resource.Resource {
return &dnsRecordResource{}
}
Expand Down
Loading