diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index ceb80fb5..7b66e9fe 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -39,6 +39,23 @@ jobs:
run: task build
- name: Format
run: task lint
+
+ docs:
+ name: Docs Test
+ timeout-minutes: 5
+ runs-on: ubuntu-latest
+ steps:
+ - name: Set up Go
+ uses: actions/setup-go@v2
+ with:
+ go-version: "1.20"
+ id: go
+ - name: Install Task
+ uses: arduino/setup-task@v1
+ with:
+ version: "3.x"
+ - name: Check out code into the Go module directory
+ uses: actions/checkout@v2
- name: Check if docs are up-to-date
run: |
task docs
@@ -48,7 +65,7 @@ jobs:
test:
name: Matrix Test
- needs: [ build ]
+ needs: [build]
timeout-minutes: 15
strategy:
max-parallel: 1
@@ -80,7 +97,7 @@ jobs:
env:
TF_ACC: "true"
VERCEL_API_TOKEN: ${{ secrets.VERCEL_API_TOKEN }}
- VERCEL_TERRAFORM_TESTING_TEAM: "team_Q8MH2GVRnqKLtxicP2HWPgLi"
+ VERCEL_TERRAFORM_TESTING_TEAM: "team_RvxIb1z0pi9RSsQ13p3ES4cK"
VERCEL_TERRAFORM_TESTING_GITHUB_REPO: "dglsparsons/test"
VERCEL_TERRAFORM_TESTING_GITLAB_REPO: "dglsparsons/test"
VERCEL_TERRAFORM_TESTING_BITBUCKET_REPO: "dglsparsons-test/test"
diff --git a/README.md b/README.md
index 545c2633..82e05b0d 100644
--- a/README.md
+++ b/README.md
@@ -23,12 +23,30 @@ If you wish to work on the provider, you'll first need [Go](http://www.golang.or
To compile the provider, run `task build`. This will build the provider and put the provider binary in the repository root.
-In addition, you can run `task install` to set up a developer overrides in your ~/.terraformrc. This will then allow you
-to use your locally built provider binary.
+```sh
+$ task build
+```
+
+In addition, you can run `task install` to set up a developer overrides in your ~/.terraformrc. This will then allow you to use your locally built provider binary.
+
+```sh
+$ task install
+```
+
+Create a `main.tf` file on your machine and use the [terraform cli](https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli#install-terraform) to test
+
+```sh
+$ terraform plan
+$ terraform apply
+```
When you are finished using a local version of the provider, running `task uninstall` will remove _all_ developer
overrides.
+```sh
+$ task uninstall
+```
+
- HashiCorp - [Development Overrides for Provider developers](https://www.terraform.io/docs/cli/config/config-file.html#development-overrides-for-provider-developers).
## Testing
@@ -42,6 +60,8 @@ The acceptance tests require a few environment variables to be set:
* `VERCEL_TERRAFORM_TESTING_TEAM` - a Vercel team_id where resources can be created and destroyed
* `VERCEL_TERRAFORM_TESTING_GITHUB_REPO` - a GitHub repository in the form 'org/repo' that can be used to trigger deployments
* `VERCEL_TERRAFORM_TESTING_BITBUCKET_REPO` - a Bitbucket repository in the form 'project/repo' that can be used to trigger deployments
+* `VERCEL_TERRAFORM_TESTING_GITLAB_REPO` - a GitLab repository in the form 'project/repo' that can be used to trigger deployments
+* `VERCEL_TERRAFORM_TESTING_DOMAIN` - a Vercel testing domain that can be used for testing
```sh
$ task test
@@ -59,6 +79,7 @@ To run a specific set of tests, use the `-run` flag and specify a regex pattern
$ task test -- -run 'TestAcc_Project*'
```
+
## Building The Documentation
The documentation is autogenerated from Description fields within the provider, and the `examples` directory.
diff --git a/Taskfile.yml b/Taskfile.yml
index 076a96b9..a46cb24c 100644
--- a/Taskfile.yml
+++ b/Taskfile.yml
@@ -23,7 +23,7 @@ tasks:
install-tfplugindocs:
desc: "Install the tfplugindocs tool"
cmds:
- - go install github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs@v0.7.0
+ - go install github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs@v0.16.0
status:
- which tfplugindocs
diff --git a/client/deployment_protection.go b/client/deployment_protection.go
new file mode 100644
index 00000000..eba07053
--- /dev/null
+++ b/client/deployment_protection.go
@@ -0,0 +1,28 @@
+package client
+
+type VercelAuthentication struct {
+ DeploymentType string `json:"deploymentType"`
+}
+
+type PasswordProtection struct {
+ DeploymentType string `json:"deploymentType"`
+}
+type PasswordProtectionWithPassword struct {
+ DeploymentType string `json:"deploymentType"`
+ Password string `json:"password"`
+}
+
+type TrustedIpAddress struct {
+ Value string `json:"value"`
+ Note string `json:"note"`
+}
+
+type TrustedIps struct {
+ DeploymentType string `json:"deploymentType"`
+ Addresses []TrustedIpAddress `json:"addresses"`
+ ProtectionMode string `json:"protectionMode"`
+}
+
+type ProtectionBypass struct {
+ Scope string `json:"scope"`
+}
diff --git a/client/must_marshal.go b/client/must_marshal.go
index 27f85dec..d4989fd5 100644
--- a/client/must_marshal.go
+++ b/client/must_marshal.go
@@ -1,6 +1,20 @@
package client
-import "encoding/json"
+import (
+ "encoding/json"
+)
+
+func (v *VercelAuthentication) MarshalJSON() ([]byte, error) {
+ if v.DeploymentType == "none" {
+ return []byte(`null`), nil
+ }
+
+ return json.Marshal(&struct {
+ DeploymentType string `json:"deploymentType"`
+ }{
+ DeploymentType: v.DeploymentType,
+ })
+}
// mustMarshal is a helper to remove unnecessary error checking when marshaling a Go
// struct to json. There are only a few instances where marshaling can fail, and they
diff --git a/client/project_get.go b/client/project_get.go
index 874637cc..b82c69c5 100644
--- a/client/project_get.go
+++ b/client/project_get.go
@@ -54,14 +54,6 @@ func (r *ProjectResponse) Repository() *Repository {
return nil
}
-type Protection struct {
- DeploymentType string `json:"deploymentType"`
-}
-
-type ProtectionBypass struct {
- Scope string `json:"scope"`
-}
-
// ProjectResponse defines the information Vercel returns about a project.
type ProjectResponse struct {
BuildCommand *string `json:"buildCommand"`
@@ -92,8 +84,9 @@ type ProjectResponse struct {
PublicSource *bool `json:"publicSource"`
RootDirectory *string `json:"rootDirectory"`
ServerlessFunctionRegion *string `json:"serverlessFunctionRegion"`
- SSOProtection *Protection `json:"ssoProtection"`
- PasswordProtection *Protection `json:"passwordProtection"`
+ VercelAuthentication *VercelAuthentication `json:"ssoProtection"`
+ PasswordProtection *PasswordProtection `json:"passwordProtection"`
+ TrustedIps *TrustedIps `json:"trustedIps"`
ProtectionBypass map[string]ProtectionBypass `json:"protectionBypass"`
}
diff --git a/client/project_update.go b/client/project_update.go
index 95f2e19d..b77a43dd 100644
--- a/client/project_update.go
+++ b/client/project_update.go
@@ -7,11 +7,6 @@ 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:
@@ -19,18 +14,19 @@ type PasswordProtectionRequest struct {
// - 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"`
- SSOProtection *Protection `json:"ssoProtection"`
- PasswordProtection *PasswordProtectionRequest `json:"passwordProtection"`
+ 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"`
+ VercelAuthentication *VercelAuthentication `json:"ssoProtection"`
+ PasswordProtection *PasswordProtectionWithPassword `json:"passwordProtection"`
+ TrustedIps *TrustedIps `json:"trustedIps"`
}
// UpdateProject updates an existing projects configuration within Vercel.
diff --git a/docs/data-sources/alias.md b/docs/data-sources/alias.md
index 3b7c7fa6..ec7e0b3e 100644
--- a/docs/data-sources/alias.md
+++ b/docs/data-sources/alias.md
@@ -30,5 +30,3 @@ An Alias allows a `vercel_deployment` to be accessed through a different URL.
- `deployment_id` (String) The ID of the Deployment the Alias is associated with.
- `id` (String) The ID of this resource.
-
-
diff --git a/docs/data-sources/file.md b/docs/data-sources/file.md
index 9ba4a959..06843acc 100644
--- a/docs/data-sources/file.md
+++ b/docs/data-sources/file.md
@@ -44,5 +44,3 @@ resource "vercel_deployment" "example" {
- `file` (Map of String) A map of filename to metadata about the file. The metadata contains the file size and hash, and allows a deployment to be created if the file changes.
- `id` (String) The ID of this resource.
-
-
diff --git a/docs/data-sources/prebuilt_project.md b/docs/data-sources/prebuilt_project.md
index 32e316eb..e335951d 100644
--- a/docs/data-sources/prebuilt_project.md
+++ b/docs/data-sources/prebuilt_project.md
@@ -65,5 +65,3 @@ resource "vercel_deployment" "example" {
- `id` (String) The ID of this resource.
- `output` (Map of String) A map of output file to metadata about the file. The metadata contains the file size and hash, and allows a deployment to be created if the file changes.
-
-
diff --git a/docs/data-sources/project.md b/docs/data-sources/project.md
index cc165bdb..c7dbec3c 100644
--- a/docs/data-sources/project.md
+++ b/docs/data-sources/project.md
@@ -38,7 +38,6 @@ 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. Required when configuring a team resource if a default team has not been set in the provider.
### Read-Only
@@ -52,19 +51,13 @@ output "project_id" {
- `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. When null is used 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) 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.
+- `trusted_ips` (Attributes) Ensures only visitors from an allowed IP address can access your deployment. (see [below for nested schema](#nestedatt--trusted_ips))
- `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))
-
-### Nested Schema for `password_protection`
-
-Optional:
-
-- `protect_production` (Boolean) If true, production deployments will also be protected
-
-
### Nested Schema for `environment`
@@ -87,11 +80,36 @@ Read-Only:
- `type` (String) The git provider of the repository. Must be either `github`, `gitlab`, or `bitbucket`.
-
-### Nested Schema for `vercel_authentication`
+
+### Nested Schema for `password_protection`
Read-Only:
-- `protect_production` (Boolean) If true, production deployments will also be protected
+- `deployment_type` (String) The deployment environment that will be protected.
+
+
+
+### Nested Schema for `trusted_ips`
+Read-Only:
+
+- `addresses` (List of Object) The allowed IP addressses and CIDR ranges with optional descriptions. (see [below for nested schema](#nestedatt--trusted_ips--addresses))
+- `deployment_type` (String) The deployment environment that will be protected.
+- `protection_mode` (String) Whether or not Trusted IPs is required or optional to access a deployment.
+
+
+### Nested Schema for `trusted_ips.addresses`
+
+Read-Only:
+
+- `note` (String)
+- `value` (String)
+
+
+
+
+### Nested Schema for `vercel_authentication`
+
+Read-Only:
+- `deployment_type` (String) The deployment environment that will be protected.
diff --git a/docs/data-sources/project_directory.md b/docs/data-sources/project_directory.md
index eed9655f..751a708c 100644
--- a/docs/data-sources/project_directory.md
+++ b/docs/data-sources/project_directory.md
@@ -58,5 +58,3 @@ resource "vercel_deployment" "example" {
- `files` (Map of String) A map of filename to metadata about the file. The metadata contains the file size and hash, and allows a deployment to be created if the file changes.
- `id` (String) The ID of this resource.
-
-
diff --git a/docs/index.md b/docs/index.md
index 7a517e1a..f872eb00 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -25,7 +25,7 @@ terraform {
required_providers {
vercel = {
source = "vercel/vercel"
- version = "~> 0.4"
+ version = "~> 1.0"
}
}
}
diff --git a/docs/resources/alias.md b/docs/resources/alias.md
index 62b03922..1a8d9cbf 100644
--- a/docs/resources/alias.md
+++ b/docs/resources/alias.md
@@ -30,5 +30,3 @@ An Alias allows a `vercel_deployment` to be accessed through a different URL.
### Read-Only
- `id` (String) The ID of this resource.
-
-
diff --git a/docs/resources/deployment.md b/docs/resources/deployment.md
index 92399b46..629a5940 100644
--- a/docs/resources/deployment.md
+++ b/docs/resources/deployment.md
@@ -129,5 +129,3 @@ Optional:
- `install_command` (String) The install command for this deployment. If omitted, this value will be taken from the project or automatically detected.
- `output_directory` (String) The output directory of the deployment. If omitted, this value will be taken from the project or automatically detected.
- `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.
-
-
diff --git a/docs/resources/dns_record.md b/docs/resources/dns_record.md
index 88a8e821..171e937f 100644
--- a/docs/resources/dns_record.md
+++ b/docs/resources/dns_record.md
@@ -124,7 +124,7 @@ For 'TXT' records, this can contain arbitrary text.
### Nested Schema for `srv`
-Optional:
+Required:
- `port` (Number) The TCP or UDP port on which the service is to be found.
- `priority` (Number) The priority of the target host, lower value means more preferred.
diff --git a/docs/resources/project.md b/docs/resources/project.md
index 069a86cd..dabfb28e 100644
--- a/docs/resources/project.md
+++ b/docs/resources/project.md
@@ -69,6 +69,7 @@ resource "vercel_project" "example" {
- `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. Required when configuring a team resource if a default team has not been set in the provider.
+- `trusted_ips` (Attributes) Ensures only visitors from an allowed IP address can access your deployment. (see [below for nested schema](#nestedatt--trusted_ips))
- `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
@@ -79,40 +80,74 @@ resource "vercel_project" "example" {
### Nested Schema for `environment`
-Optional:
+Required:
-- `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.
- `target` (Set of String) The environments that the Environment Variable should be present on. Valid targets are either `production`, `preview`, or `development`.
- `value` (String, Sensitive) The value of the Environment Variable.
+Optional:
+
+- `git_branch` (String) The git branch of the Environment Variable.
+
+Read-Only:
+
+- `id` (String) The ID of the Environment Variable.
+
### Nested Schema for `git_repository`
-Optional:
+Required:
-- `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.
- `repo` (String) The name of the git repository. For example: `vercel/next.js`.
- `type` (String) The git provider of the repository. Must be either `github`, `gitlab`, or `bitbucket`.
+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.
+
### Nested Schema for `password_protection`
-Optional:
+Required:
+- `deployment_type` (String) The deployment environment to protect. Must be one of `standard_protection`, `all_deployments`, or `only_preview_deployments`.
- `password` (String, Sensitive) The password that visitors must enter to gain access to your Preview Deployments. Drift detection is not possible for this field.
-- `protect_production` (Boolean) If true, production deployments will also be protected
+
+
+
+### Nested Schema for `trusted_ips`
+
+Required:
+
+- `addresses` (Attributes Set) The allowed IP addressses and CIDR ranges with optional descriptions. (see [below for nested schema](#nestedatt--trusted_ips--addresses))
+- `deployment_type` (String) The deployment environment to protect. Must be one of `standard_protection`, `all_deployments`, `only_production_deployments`, or `only_preview_deployments`.
+
+Optional:
+
+- `protection_mode` (String) Whether or not Trusted IPs is optional to access a deployment. Must be either `trusted_ip_required` or `trusted_ip_optional`. `trusted_ip_optional` is only available with Standalone Trusted IPs.
+
+
+### Nested Schema for `trusted_ips.addresses`
+
+Required:
+
+- `value` (String, Sensitive) The address or CIDR range that can access deployments.
+
+Optional:
+
+- `note` (String) A description for the value
+
### Nested Schema for `vercel_authentication`
-Optional:
+Required:
-- `protect_production` (Boolean) If true, production deployments will also be protected
+- `deployment_type` (String) The deployment environment to protect. Must be one of `standard_protection`, `all_deployments`, `only_preview_deployments`, or `none`.
## Import
diff --git a/examples/provider/provider.tf b/examples/provider/provider.tf
index ce63b5fc..a82ab0fb 100644
--- a/examples/provider/provider.tf
+++ b/examples/provider/provider.tf
@@ -5,7 +5,7 @@ terraform {
required_providers {
vercel = {
source = "vercel/vercel"
- version = "~> 0.4"
+ version = "~> 1.0"
}
}
}
diff --git a/vercel/data_source_project.go b/vercel/data_source_project.go
index 2c6bb7b4..ff92a180 100644
--- a/vercel/data_source_project.go
+++ b/vercel/data_source_project.go
@@ -5,6 +5,7 @@ import (
"fmt"
"regexp"
+ "github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
@@ -149,18 +150,42 @@ For more detailed information, please see the [Vercel documentation](https://ver
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",
+ "deployment_type": schema.StringAttribute{
+ Description: "The deployment environment that will 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,
+ Computed: true,
Attributes: map[string]schema.Attribute{
- "protect_production": schema.BoolAttribute{
- Description: "If true, production deployments will also be protected",
+ "deployment_type": schema.StringAttribute{
+ Description: "The deployment environment that will be protected.",
+ Computed: true,
+ },
+ },
+ },
+ "trusted_ips": schema.SingleNestedAttribute{
+ Description: "Ensures only visitors from an allowed IP address can access your deployment.",
+ Computed: true,
+ Attributes: map[string]schema.Attribute{
+ "deployment_type": schema.StringAttribute{
+ Description: "The deployment environment that will be protected.",
+ Computed: true,
+ },
+ "addresses": schema.ListAttribute{
+ Description: "The allowed IP addressses and CIDR ranges with optional descriptions.",
+ Computed: true,
+ ElementType: types.ObjectType{
+ AttrTypes: map[string]attr.Type{
+ "value": types.StringType,
+ "note": types.StringType,
+ },
+ },
+ },
+ "protection_mode": schema.StringAttribute{
+ Description: "Whether or not Trusted IPs is required or optional to access a deployment.",
Computed: true,
},
},
diff --git a/vercel/data_source_project_model.go b/vercel/data_source_project_model.go
index 451807cb..6e2d780f 100644
--- a/vercel/data_source_project_model.go
+++ b/vercel/data_source_project_model.go
@@ -7,35 +7,32 @@ import (
// 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"`
+ 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 *PasswordProtection `tfsdk:"password_protection"`
+ TrustedIps *TrustedIps `tfsdk:"trusted_ips"`
}
func convertResponseToProjectDataSource(response client.ProjectResponse, plan Project) ProjectDataSource {
project := convertResponseToProject(response, plan)
- var pp *PasswordProtectionDataSource
+ var pp *PasswordProtection
if project.PasswordProtection != nil {
- pp = &PasswordProtectionDataSource{
- ProtectProduction: project.PasswordProtection.ProtectProduction,
+ pp = &PasswordProtection{
+ DeploymentType: project.PasswordProtection.DeploymentType,
}
}
return ProjectDataSource{
@@ -55,5 +52,6 @@ func convertResponseToProjectDataSource(response client.ProjectResponse, plan Pr
TeamID: project.TeamID,
VercelAuthentication: project.VercelAuthentication,
PasswordProtection: pp,
+ TrustedIps: project.TrustedIps,
}
}
diff --git a/vercel/data_source_project_test.go b/vercel/data_source_project_test.go
index b199f751..e107a21a 100644
--- a/vercel/data_source_project_test.go
+++ b/vercel/data_source_project_test.go
@@ -25,8 +25,16 @@ 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.TestCheckResourceAttr("data.vercel_project.test", "vercel_authentication.deployment_type", "standard_protection"),
+ resource.TestCheckResourceAttr("data.vercel_project.test", "password_protection.deployment_type", "standard_protection"),
+ resource.TestCheckResourceAttr("data.vercel_project.test", "trusted_ips.addresses.#", "1"),
+ resource.TestCheckTypeSetElemNestedAttrs("data.vercel_project.test", "trusted_ips.addresses.*", map[string]string{
+ "value": "1.1.1.1",
+ "note": "notey note",
+ }),
+ resource.TestCheckResourceAttr("data.vercel_project.test", "trusted_ips.deployment_type", "only_production_deployments"),
+ resource.TestCheckResourceAttr("data.vercel_project.test", "trusted_ips.protection_mode", "trusted_ip_required"),
+
resource.TestCheckTypeSetElemNestedAttrs("data.vercel_project.test", "environment.*", map[string]string{
"key": "foo",
"value": "bar",
@@ -50,11 +58,21 @@ resource "vercel_project" "test" {
public_source = true
root_directory = "ui/src"
vercel_authentication = {
- protect_production = true
+ deployment_type = "standard_protection"
}
password_protection = {
password = "foo"
- protect_production = true
+ deployment_type = "standard_protection"
+ }
+ trusted_ips = {
+ addresses = [
+ {
+ value = "1.1.1.1"
+ note = "notey note"
+ }
+ ]
+ deployment_type = "only_production_deployments"
+ protection_mode = "trusted_ip_required"
}
%s
environment = [
diff --git a/vercel/deployment_protection.go b/vercel/deployment_protection.go
new file mode 100644
index 00000000..6bb8f354
--- /dev/null
+++ b/vercel/deployment_protection.go
@@ -0,0 +1,30 @@
+package vercel
+
+import "github.com/hashicorp/terraform-plugin-framework/types"
+
+type VercelAuthentication struct {
+ DeploymentType types.String `tfsdk:"deployment_type"`
+}
+
+type PasswordProtection struct {
+ DeploymentType types.String `tfsdk:"deployment_type"`
+}
+type PasswordProtectionWithPassword struct {
+ DeploymentType types.String `tfsdk:"deployment_type"`
+ Password types.String `tfsdk:"password"`
+}
+
+type TrustedIpAddress struct {
+ Value types.String `tfsdk:"value"`
+ Note types.String `tfsdk:"note"`
+}
+
+type TrustedIps struct {
+ DeploymentType types.String `tfsdk:"deployment_type"`
+ Addresses []TrustedIpAddress `tfsdk:"addresses"`
+ ProtectionMode types.String `tfsdk:"protection_mode"`
+}
+
+type ProtectionBypass struct {
+ Scope types.String `tfsdk:"scope"`
+}
diff --git a/vercel/resource_project.go b/vercel/resource_project.go
index 2dc4d810..bb1d79f1 100644
--- a/vercel/resource_project.go
+++ b/vercel/resource_project.go
@@ -9,10 +9,11 @@ import (
"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
- "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/objectdefault"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/objectplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
@@ -174,23 +175,26 @@ At this time you cannot use a Vercel Project resource with in-line ` + "`environ
},
},
"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.",
- Optional: true,
- Computed: true,
+ Description: "Ensures visitors to your Preview Deployments are logged into Vercel and have a minimum of Viewer access on your team.",
+ Optional: true,
+ Computed: true,
+ PlanModifiers: []planmodifier.Object{objectplanmodifier.UseStateForUnknown()},
Default: objectdefault.StaticValue(types.ObjectValueMust(
map[string]attr.Type{
- "protect_production": types.BoolType,
+ "deployment_type": types.StringType,
},
map[string]attr.Value{
- "protect_production": types.BoolValue(false),
+ "deployment_type": types.StringValue("standard_protection"),
},
)),
Attributes: map[string]schema.Attribute{
- "protect_production": schema.BoolAttribute{
- Description: "If true, production deployments will also be protected",
- Optional: true,
- Computed: true,
- Default: booldefault.StaticBool(false),
+ "deployment_type": schema.StringAttribute{
+ Required: true,
+ Description: "The deployment environment to protect. Must be one of `standard_protection`, `all_deployments`, `only_preview_deployments`, or `none`.",
+ PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()},
+ Validators: []validator.String{
+ stringOneOf("standard_protection", "all_deployments", "only_preview_deployments", "none"),
+ },
},
},
},
@@ -206,11 +210,58 @@ At this time you cannot use a Vercel Project resource with in-line ` + "`environ
stringLengthBetween(1, 72),
},
},
- "protect_production": schema.BoolAttribute{
- Description: "If true, production deployments will also be protected",
- Optional: true,
- Computed: true,
- Default: booldefault.StaticBool(false),
+ "deployment_type": schema.StringAttribute{
+ Required: true,
+ Description: "The deployment environment to protect. Must be one of `standard_protection`, `all_deployments`, or `only_preview_deployments`.",
+ PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()},
+ Validators: []validator.String{
+ stringOneOf("standard_protection", "all_deployments", "only_preview_deployments"),
+ },
+ },
+ },
+ },
+ "trusted_ips": schema.SingleNestedAttribute{
+ Description: "Ensures only visitors from an allowed IP address can access your deployment.",
+ Optional: true,
+ Attributes: map[string]schema.Attribute{
+ "addresses": schema.SetNestedAttribute{
+ Description: "The allowed IP addressses and CIDR ranges with optional descriptions.",
+ Required: true,
+ PlanModifiers: []planmodifier.Set{setplanmodifier.UseStateForUnknown()},
+ NestedObject: schema.NestedAttributeObject{
+ Attributes: map[string]schema.Attribute{
+ "value": schema.StringAttribute{
+ Description: "The address or CIDR range that can access deployments.",
+ Required: true,
+ Sensitive: true,
+ },
+ "note": schema.StringAttribute{
+ Description: "A description for the value",
+ Optional: true,
+ },
+ },
+ },
+ Validators: []validator.Set{
+ stringSetMinCount(1),
+ },
+ },
+ "deployment_type": schema.StringAttribute{
+ Required: true,
+ Description: "The deployment environment to protect. Must be one of `standard_protection`, `all_deployments`, `only_production_deployments`, or `only_preview_deployments`.",
+ PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()},
+ Validators: []validator.String{
+ stringOneOf("standard_protection", "all_deployments", "only_production_deployments", "only_preview_deployments"),
+ },
+ },
+ "protection_mode": schema.StringAttribute{
+ Optional: true,
+ Computed: true,
+ Default: stringdefault.StaticString("trusted_ip_required"),
+ Description: "Whether or not Trusted IPs is optional to access a deployment. Must be either `trusted_ip_required` or `trusted_ip_optional`. `trusted_ip_optional` is only available with Standalone Trusted IPs.",
+ PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()},
+ Validators: []validator.String{
+ stringOneOf("trusted_ip_required", "trusted_ip_optional"),
+ },
},
},
},
@@ -285,7 +336,7 @@ func (r *projectResource) Create(ctx context.Context, req resource.CreateRequest
return
}
- if plan.PasswordProtection != nil || plan.VercelAuthentication != nil {
+ if plan.PasswordProtection != nil || plan.VercelAuthentication != nil || plan.TrustedIps != nil {
out, err = r.client.UpdateProject(ctx, result.ID.ValueString(), plan.TeamID.ValueString(), plan.toUpdateProjectRequest(plan.Name.ValueString()), !plan.Environment.IsNull())
if err != nil {
resp.Diagnostics.AddError(
diff --git a/vercel/resource_project_model.go b/vercel/resource_project_model.go
index 911cd31c..ae4d8669 100644
--- a/vercel/resource_project_model.go
+++ b/vercel/resource_project_model.go
@@ -11,24 +11,25 @@ import (
// Project reflects the state terraform stores internally for a project.
type Project 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 *PasswordProtection `tfsdk:"password_protection"`
- ProtectionBypassForAutomation types.Bool `tfsdk:"protection_bypass_for_automation"`
- ProtectionBypassForAutomationSecret types.String `tfsdk:"protection_bypass_for_automation_secret"`
+ 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 *PasswordProtectionWithPassword `tfsdk:"password_protection"`
+ TrustedIps *TrustedIps `tfsdk:"trusted_ips"`
+ ProtectionBypassForAutomation types.Bool `tfsdk:"protection_bypass_for_automation"`
+ ProtectionBypassForAutomationSecret types.String `tfsdk:"protection_bypass_for_automation_secret"`
}
var nullProject = Project{
@@ -109,7 +110,8 @@ func (p *Project) toUpdateProjectRequest(oldName string) client.UpdateProjectReq
RootDirectory: toStrPointer(p.RootDirectory),
ServerlessFunctionRegion: toStrPointer(p.ServerlessFunctionRegion),
PasswordProtection: p.PasswordProtection.toUpdateProjectRequest(),
- SSOProtection: p.VercelAuthentication.toUpdateProjectRequest(),
+ VercelAuthentication: p.VercelAuthentication.toUpdateProjectRequest(),
+ TrustedIps: p.TrustedIps.toUpdateProjectRequest(),
}
}
@@ -153,43 +155,96 @@ func (g *GitRepository) toCreateProjectRequest() *client.GitRepository {
}
}
-type VercelAuthentication struct {
- ProtectProduction types.Bool `tfsdk:"protect_production"`
+func toApiDeploymentProtectionType(dt types.String) string {
+ switch dt {
+ case types.StringValue("standard_protection"):
+ return "prod_deployment_urls_and_all_previews"
+ case types.StringValue("all_deployments"):
+ return "all"
+ case types.StringValue("only_preview_deployments"):
+ return "preview"
+ case types.StringValue("only_production_deployments"):
+ return "production"
+ default:
+ return dt.ValueString()
+ }
+}
+
+func fromApiDeploymentProtectionType(dt string) types.String {
+ switch dt {
+ case "prod_deployment_urls_and_all_previews":
+ return types.StringValue("standard_protection")
+ case "all":
+ return types.StringValue("all_deployments")
+ case "preview":
+ return types.StringValue("only_preview_deployments")
+ case "production":
+ return types.StringValue("only_production_deployments")
+ default:
+ return types.StringValue(dt)
+ }
}
-func (v *VercelAuthentication) toUpdateProjectRequest() *client.Protection {
+func (v *VercelAuthentication) toUpdateProjectRequest() *client.VercelAuthentication {
if v == nil {
return nil
}
- deploymentType := "preview"
- if v.ProtectProduction.ValueBool() {
- deploymentType = "all"
+ return &client.VercelAuthentication{
+ DeploymentType: toApiDeploymentProtectionType(v.DeploymentType),
+ }
+}
+
+func (p *PasswordProtectionWithPassword) toUpdateProjectRequest() *client.PasswordProtectionWithPassword {
+ if p == nil {
+ return nil
+ }
+
+ return &client.PasswordProtectionWithPassword{
+ DeploymentType: toApiDeploymentProtectionType(p.DeploymentType),
+ Password: p.Password.ValueString(),
}
+}
- return &client.Protection{
- DeploymentType: deploymentType,
+func toApiTrustedIpProtectionMode(dt types.String) string {
+ switch dt {
+ case types.StringValue("trusted_ip_required"):
+ return "additional"
+ case types.StringValue("trusted_ip_optional"):
+ return "exclusive"
+ default:
+ return dt.ValueString()
}
}
-type PasswordProtection struct {
- Password types.String `tfsdk:"password"`
- ProtectProduction types.Bool `tfsdk:"protect_production"`
+func fromApiTrustedIpProtectionMode(dt string) types.String {
+ switch dt {
+ case "additional":
+ return types.StringValue("trusted_ip_required")
+ case "exclusive":
+ return types.StringValue("trusted_ip_optional")
+ default:
+ return types.StringValue(dt)
+ }
}
-func (p *PasswordProtection) toUpdateProjectRequest() *client.PasswordProtectionRequest {
- if p == nil {
+func (t *TrustedIps) toUpdateProjectRequest() *client.TrustedIps {
+ if t == nil {
return nil
}
- deploymentType := "preview"
- if p.ProtectProduction.ValueBool() {
- deploymentType = "all"
+ var addresses = []client.TrustedIpAddress{}
+ for _, address := range t.Addresses {
+ addresses = append(addresses, client.TrustedIpAddress{
+ Value: address.Value.ValueString(),
+ Note: address.Note.ValueString(),
+ })
}
- return &client.PasswordProtectionRequest{
- DeploymentType: deploymentType,
- Password: p.Password.ValueString(),
+ return &client.TrustedIps{
+ Addresses: addresses,
+ DeploymentType: toApiDeploymentProtectionType(t.DeploymentType),
+ ProtectionMode: toApiTrustedIpProtectionMode(t.ProtectionMode),
}
}
@@ -266,22 +321,40 @@ func convertResponseToProject(response client.ProjectResponse, plan Project) Pro
}
}
- var pp *PasswordProtection
+ var pp *PasswordProtectionWithPassword
if response.PasswordProtection != nil {
pass := types.StringValue("")
if plan.PasswordProtection != nil {
pass = plan.PasswordProtection.Password
}
- pp = &PasswordProtection{
- Password: pass,
- ProtectProduction: types.BoolValue(response.PasswordProtection.DeploymentType == "all"),
+ pp = &PasswordProtectionWithPassword{
+ Password: pass,
+ DeploymentType: fromApiDeploymentProtectionType(response.PasswordProtection.DeploymentType),
}
}
- var va *VercelAuthentication
- if response.SSOProtection != nil {
+ var va *VercelAuthentication = &VercelAuthentication{
+ DeploymentType: types.StringValue("none"),
+ }
+ if response.VercelAuthentication != nil {
va = &VercelAuthentication{
- ProtectProduction: types.BoolValue(response.SSOProtection.DeploymentType == "all"),
+ DeploymentType: fromApiDeploymentProtectionType(response.VercelAuthentication.DeploymentType),
+ }
+ }
+
+ var tip *TrustedIps
+ if response.TrustedIps != nil {
+ var addresses []TrustedIpAddress
+ for _, address := range response.TrustedIps.Addresses {
+ addresses = append(addresses, TrustedIpAddress{
+ Value: types.StringValue(address.Value),
+ Note: types.StringValue(address.Note),
+ })
+ }
+ tip = &TrustedIps{
+ DeploymentType: fromApiDeploymentProtectionType(response.TrustedIps.DeploymentType),
+ Addresses: addresses,
+ ProtectionMode: fromApiTrustedIpProtectionMode(response.TrustedIps.ProtectionMode),
}
}
@@ -346,6 +419,7 @@ func convertResponseToProject(response client.ProjectResponse, plan Project) Pro
TeamID: toTeamID(response.TeamID),
PasswordProtection: pp,
VercelAuthentication: va,
+ TrustedIps: tip,
ProtectionBypassForAutomation: protectionBypass,
ProtectionBypassForAutomationSecret: protectionBypassSecret,
}
diff --git a/vercel/resource_project_test.go b/vercel/resource_project_test.go
index 41964115..11a7a3da 100644
--- a/vercel/resource_project_test.go
+++ b/vercel/resource_project_test.go
@@ -146,7 +146,7 @@ func TestAcc_ProjectWithGitRepository(t *testing.T) {
})
}
-func TestAcc_ProjectWithSSOAndPasswordProtection(t *testing.T) {
+func TestAcc_ProjectWithVercelAuthAndPasswordProtectionAndTrustedIps(t *testing.T) {
projectSuffix := acctest.RandString(16)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
@@ -154,44 +154,74 @@ func TestAcc_ProjectWithSSOAndPasswordProtection(t *testing.T) {
CheckDestroy: testAccProjectDestroy("vercel_project.enabled_to_start", testTeam()),
Steps: []resource.TestStep{
{
- Config: testAccProjectConfigWithSSOAndPassword(projectSuffix, teamIDConfig()),
+ Config: testAccProjectConfigWithVercelAuthAndPasswordAndTrustedIps(projectSuffix, teamIDConfig()),
Check: resource.ComposeAggregateTestCheckFunc(
testAccProjectExists("vercel_project.enabled_to_start", testTeam()),
- resource.TestCheckResourceAttr("vercel_project.enabled_to_start", "vercel_authentication.protect_production", "true"),
- resource.TestCheckResourceAttr("vercel_project.enabled_to_start", "password_protection.protect_production", "true"),
+ resource.TestCheckResourceAttr("vercel_project.enabled_to_start", "vercel_authentication.deployment_type", "all_deployments"),
+ resource.TestCheckResourceAttr("vercel_project.enabled_to_start", "password_protection.deployment_type", "all_deployments"),
resource.TestCheckResourceAttr("vercel_project.enabled_to_start", "password_protection.password", "password"),
+ resource.TestCheckResourceAttr("vercel_project.enabled_to_start", "trusted_ips.addresses.#", "1"),
+ resource.TestCheckTypeSetElemNestedAttrs("vercel_project.enabled_to_start", "trusted_ips.addresses.*", map[string]string{
+ "value": "1.1.1.1",
+ "note": "notey note",
+ }),
+ resource.TestCheckResourceAttr("vercel_project.enabled_to_start", "trusted_ips.deployment_type", "all_deployments"),
+ resource.TestCheckResourceAttr("vercel_project.enabled_to_start", "trusted_ips.protection_mode", "trusted_ip_optional"),
resource.TestCheckResourceAttr("vercel_project.enabled_to_start", "protection_bypass_for_automation", "true"),
resource.TestCheckResourceAttrSet("vercel_project.enabled_to_start", "protection_bypass_for_automation_secret"),
testAccProjectExists("vercel_project.disabled_to_start", testTeam()),
- resource.TestCheckNoResourceAttr("vercel_project.disabled_to_start", "vercel_authentication"),
+ resource.TestCheckResourceAttr("vercel_project.disabled_to_start", "vercel_authentication.deployment_type", "standard_protection"),
resource.TestCheckNoResourceAttr("vercel_project.disabled_to_start", "password_protection"),
+ resource.TestCheckNoResourceAttr("vercel_project.disabled_to_start", "trusted_ips"),
resource.TestCheckNoResourceAttr("vercel_project.disabled_to_start", "protection_bypass_for_automation"),
resource.TestCheckNoResourceAttr("vercel_project.disabled_to_start", "protection_bypass_for_automation_secret"),
testAccProjectExists("vercel_project.enabled_to_update", testTeam()),
- resource.TestCheckResourceAttr("vercel_project.enabled_to_update", "vercel_authentication.protect_production", "false"),
- resource.TestCheckResourceAttr("vercel_project.enabled_to_update", "password_protection.protect_production", "false"),
+ resource.TestCheckResourceAttr("vercel_project.enabled_to_update", "vercel_authentication.deployment_type", "only_preview_deployments"),
+ resource.TestCheckResourceAttr("vercel_project.enabled_to_update", "password_protection.deployment_type", "only_preview_deployments"),
resource.TestCheckResourceAttr("vercel_project.enabled_to_update", "password_protection.password", "password"),
+ resource.TestCheckResourceAttr("vercel_project.enabled_to_update", "trusted_ips.addresses.#", "2"),
+ resource.TestCheckTypeSetElemNestedAttrs("vercel_project.enabled_to_update", "trusted_ips.addresses.*", map[string]string{
+ "value": "1.1.1.3",
+ "note": "notey notey note",
+ }),
+ resource.TestCheckResourceAttr("vercel_project.enabled_to_update", "trusted_ips.deployment_type", "only_production_deployments"),
+ resource.TestCheckResourceAttr("vercel_project.enabled_to_update", "trusted_ips.protection_mode", "trusted_ip_required"),
resource.TestCheckResourceAttr("vercel_project.enabled_to_update", "protection_bypass_for_automation", "true"),
resource.TestCheckResourceAttrSet("vercel_project.enabled_to_update", "protection_bypass_for_automation_secret"),
),
},
{
- Config: testAccProjectConfigWithSSOAndPasswordUpdated(projectSuffix, teamIDConfig()),
+ Config: testAccProjectConfigWithVercelAuthAndPasswordAndTrustedIpsUpdated(projectSuffix, teamIDConfig()),
Check: resource.ComposeAggregateTestCheckFunc(
- resource.TestCheckNoResourceAttr("vercel_project.enabled_to_start", "vercel_authentication"),
+ resource.TestCheckResourceAttr("vercel_project.enabled_to_start", "vercel_authentication.deployment_type", "standard_protection"),
resource.TestCheckNoResourceAttr("vercel_project.enabled_to_start", "password_protection"),
resource.TestCheckNoResourceAttr("vercel_project.enabled_to_start", "protection_bypass_for_automation"),
+ resource.TestCheckNoResourceAttr("vercel_project.enabled_to_start", "trusted_ips"),
resource.TestCheckNoResourceAttr("vercel_project.enabled_to_start", "protection_bypass_for_automation_secret"),
- resource.TestCheckResourceAttr("vercel_project.disabled_to_start", "vercel_authentication.protect_production", "true"),
- resource.TestCheckResourceAttr("vercel_project.disabled_to_start", "password_protection.protect_production", "true"),
+ resource.TestCheckResourceAttr("vercel_project.disabled_to_start", "vercel_authentication.deployment_type", "standard_protection"),
+ resource.TestCheckResourceAttr("vercel_project.disabled_to_start", "password_protection.deployment_type", "standard_protection"),
resource.TestCheckResourceAttr("vercel_project.disabled_to_start", "password_protection.password", "password"),
+ resource.TestCheckResourceAttr("vercel_project.disabled_to_start", "trusted_ips.addresses.#", "1"),
+ resource.TestCheckTypeSetElemNestedAttrs("vercel_project.disabled_to_start", "trusted_ips.addresses.*", map[string]string{
+ "value": "1.1.1.1",
+ "note": "notey note",
+ }),
+ resource.TestCheckResourceAttr("vercel_project.disabled_to_start", "trusted_ips.deployment_type", "standard_protection"),
+ resource.TestCheckResourceAttr("vercel_project.disabled_to_start", "trusted_ips.protection_mode", "trusted_ip_required"),
resource.TestCheckResourceAttr("vercel_project.disabled_to_start", "protection_bypass_for_automation", "true"),
resource.TestCheckResourceAttrSet("vercel_project.disabled_to_start", "protection_bypass_for_automation_secret"),
- resource.TestCheckResourceAttr("vercel_project.enabled_to_update", "vercel_authentication.protect_production", "true"),
- resource.TestCheckResourceAttr("vercel_project.enabled_to_update", "password_protection.protect_production", "true"),
+ resource.TestCheckResourceAttr("vercel_project.enabled_to_update", "vercel_authentication.deployment_type", "standard_protection"),
+ resource.TestCheckResourceAttr("vercel_project.enabled_to_update", "password_protection.deployment_type", "standard_protection"),
resource.TestCheckResourceAttr("vercel_project.enabled_to_update", "password_protection.password", "password2"),
+ resource.TestCheckResourceAttr("vercel_project.enabled_to_update", "trusted_ips.addresses.#", "1"),
+ resource.TestCheckTypeSetElemNestedAttrs("vercel_project.enabled_to_update", "trusted_ips.addresses.*", map[string]string{
+ "value": "1.1.1.3",
+ "note": "notey notey",
+ }),
+ resource.TestCheckResourceAttr("vercel_project.enabled_to_update", "trusted_ips.deployment_type", "all_deployments"),
+ resource.TestCheckResourceAttr("vercel_project.enabled_to_update", "trusted_ips.protection_mode", "trusted_ip_optional"),
resource.TestCheckResourceAttr("vercel_project.enabled_to_update", "protection_bypass_for_automation", "false"),
resource.TestCheckNoResourceAttr("vercel_project.enabled_to_update", "protection_bypass_for_automation_secret"),
),
@@ -330,18 +360,28 @@ resource "vercel_project" "test" {
`, projectSuffix, teamID)
}
-func testAccProjectConfigWithSSOAndPassword(projectSuffix, teamID string) string {
+func testAccProjectConfigWithVercelAuthAndPasswordAndTrustedIps(projectSuffix, teamID string) string {
return fmt.Sprintf(`
resource "vercel_project" "enabled_to_start" {
name = "test-acc-protection-one-%[1]s"
%[2]s
vercel_authentication = {
- protect_production = true
+ deployment_type = "all_deployments"
}
password_protection = {
- protect_production = true
+ deployment_type = "all_deployments"
password = "password"
}
+ trusted_ips = {
+ addresses = [
+ {
+ value = "1.1.1.1"
+ note = "notey note"
+ }
+ ]
+ deployment_type = "all_deployments"
+ protection_mode = "trusted_ip_optional"
+ }
protection_bypass_for_automation = true
}
@@ -354,18 +394,31 @@ resource "vercel_project" "enabled_to_update" {
name = "test-acc-protection-three-%[1]s"
%[2]s
vercel_authentication = {
- protect_production = false
+ deployment_type = "only_preview_deployments"
}
password_protection = {
- protect_production = false
+ deployment_type = "only_preview_deployments"
password = "password"
}
+ trusted_ips = {
+ addresses = [
+ {
+ value = "1.1.1.1"
+ note = "notey notey"
+ },
+ {
+ value = "1.1.1.3"
+ note = "notey notey note"
+ }
+ ]
+ deployment_type = "only_production_deployments"
+ }
protection_bypass_for_automation = true
}
`, projectSuffix, teamID)
}
-func testAccProjectConfigWithSSOAndPasswordUpdated(projectSuffix, teamID string) string {
+func testAccProjectConfigWithVercelAuthAndPasswordAndTrustedIpsUpdated(projectSuffix, teamID string) string {
return fmt.Sprintf(`
resource "vercel_project" "enabled_to_start" {
name = "test-acc-protection-one-%[1]s"
@@ -376,12 +429,21 @@ resource "vercel_project" "disabled_to_start" {
name = "test-acc-protection-two-%[1]s"
%[2]s
vercel_authentication = {
- protect_production = true
+ deployment_type = "standard_protection"
}
password_protection = {
- protect_production = true
+ deployment_type = "standard_protection"
password = "password"
}
+ trusted_ips = {
+ addresses = [
+ {
+ value = "1.1.1.1"
+ note = "notey note"
+ }
+ ]
+ deployment_type = "standard_protection"
+ }
protection_bypass_for_automation = true
}
@@ -389,12 +451,22 @@ resource "vercel_project" "enabled_to_update" {
name = "test-acc-protection-three-%[1]s"
%[2]s
vercel_authentication = {
- protect_production = true
+ deployment_type = "standard_protection"
}
password_protection = {
- protect_production = true
+ deployment_type = "standard_protection"
password = "password2"
}
+ trusted_ips = {
+ addresses = [
+ {
+ value = "1.1.1.3"
+ note = "notey notey"
+ }
+ ]
+ deployment_type = "all_deployments"
+ protection_mode = "trusted_ip_optional"
+ }
protection_bypass_for_automation = false
}
`, projectSuffix, teamID)