diff --git a/go.mod b/go.mod index 1c16046f..d6dbd6eb 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,8 @@ module github.com/vercel/terraform-provider-vercel go 1.19 require ( - github.com/hashicorp/terraform-plugin-framework v0.16.0 - github.com/hashicorp/terraform-plugin-go v0.14.1 + github.com/hashicorp/terraform-plugin-framework v0.17.0 + github.com/hashicorp/terraform-plugin-go v0.14.2 github.com/hashicorp/terraform-plugin-log v0.7.0 github.com/hashicorp/terraform-plugin-sdk/v2 v2.10.1 github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 @@ -53,7 +53,7 @@ require ( golang.org/x/sys v0.2.0 // indirect golang.org/x/text v0.4.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20221114212237-e4508ebdbee1 // indirect - google.golang.org/grpc v1.50.1 // indirect + google.golang.org/genproto v0.0.0-20221130183247-a2ec334bae6f // indirect + google.golang.org/grpc v1.51.0 // indirect google.golang.org/protobuf v1.28.1 // indirect ) diff --git a/go.sum b/go.sum index 354eb128..cb00b728 100644 --- a/go.sum +++ b/go.sum @@ -209,11 +209,11 @@ github.com/hashicorp/terraform-exec v0.15.0 h1:cqjh4d8HYNQrDoEmlSGelHmg2DYDh5yay github.com/hashicorp/terraform-exec v0.15.0/go.mod h1:H4IG8ZxanU+NW0ZpDRNsvh9f0ul7C0nHP+rUR/CHs7I= github.com/hashicorp/terraform-json v0.13.0 h1:Li9L+lKD1FO5RVFRM1mMMIBDoUHslOniyEi5CM+FWGY= github.com/hashicorp/terraform-json v0.13.0/go.mod h1:y5OdLBCT+rxbwnpxZs9kGL7R9ExU76+cpdY8zHwoazk= -github.com/hashicorp/terraform-plugin-framework v0.16.0 h1:kEHh0d6dp5Ig/ey6PYXkWDZPMLIW8Me41T/Oa7bpO4s= -github.com/hashicorp/terraform-plugin-framework v0.16.0/go.mod h1:Vk5MuIJoE1qksHZawAZr6psx6YXsQBFIKDrWbROrwus= +github.com/hashicorp/terraform-plugin-framework v0.17.0 h1:0KUOY/oe1GPLFqaXnKDnd1rhCrnUtt8pV9wGEwNUFlU= +github.com/hashicorp/terraform-plugin-framework v0.17.0/go.mod h1:FV97t2BZOARkL7NNlsc/N25c84MyeSSz72uPp7Vq1lg= github.com/hashicorp/terraform-plugin-go v0.5.0/go.mod h1:PAVN26PNGpkkmsvva1qfriae5Arky3xl3NfzKa8XFVM= -github.com/hashicorp/terraform-plugin-go v0.14.1 h1:cwZzPYla82XwAqpLhSzdVsOMU+6H29tczAwrB0z9Zek= -github.com/hashicorp/terraform-plugin-go v0.14.1/go.mod h1:Bc/K6K26BQ2FHqIELPbpKtt2CzzbQou+0UQF3/0NsCQ= +github.com/hashicorp/terraform-plugin-go v0.14.2 h1:rhsVEOGCnY04msNymSvbUsXfRLKh9znXZmHlf5e8mhE= +github.com/hashicorp/terraform-plugin-go v0.14.2/go.mod h1:Q12UjumPNGiFsZffxOsA40Tlz1WVXt2Evh865Zj0+UA= github.com/hashicorp/terraform-plugin-log v0.2.0/go.mod h1:E1kJmapEHzqu1x6M++gjvhzM2yMQNXPVWZRCB8sgYjg= github.com/hashicorp/terraform-plugin-log v0.7.0 h1:SDxJUyT8TwN4l5b5/VkiTIaQgY6R+Y2BQ0sRZftGKQs= github.com/hashicorp/terraform-plugin-log v0.7.0/go.mod h1:p4R1jWBXRTvL4odmEkFfDdhUjHf9zcs/BCoNHAc7IK4= @@ -297,7 +297,6 @@ github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nsf/jsondiff v0.0.0-20200515183724-f29ed568f4ce h1:RPclfga2SEJmgMmz2k+Mg7cowZ8yv4Trqw9UsJby758= github.com/nsf/jsondiff v0.0.0-20200515183724-f29ed568f4ce/go.mod h1:uFMI8w+ref4v2r9jz+c9i1IfIttS/OkmLfrk1jne5hs= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= @@ -592,8 +591,8 @@ google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1m google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200711021454-869866162049/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20221114212237-e4508ebdbee1 h1:jCw9YRd2s40X9Vxi4zKsPRvSPlHWNqadVkpbMsCPzPQ= -google.golang.org/genproto v0.0.0-20221114212237-e4508ebdbee1/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221130183247-a2ec334bae6f h1:G9JGt1JAvAkcv0+x6gGEWkgjEPxsI3fQhNq6L/DJTZ8= +google.golang.org/genproto v0.0.0-20221130183247-a2ec334bae6f/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -607,8 +606,8 @@ google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.50.1 h1:DS/BukOZWp8s6p4Dt/tOaJaTQyPyOoCcrjroHuCeLzY= -google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.51.0 h1:E1eGv1FTqoLIdnBCZufiSHgKjlqG6fKFf6pPWtMTh8U= +google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/vercel/data_source_alias.go b/vercel/data_source_alias.go index b200a17e..59d9a0a9 100644 --- a/vercel/data_source_alias.go +++ b/vercel/data_source_alias.go @@ -5,9 +5,7 @@ import ( "fmt" "github.com/hashicorp/terraform-plugin-framework/datasource" - "github.com/hashicorp/terraform-plugin-framework/diag" - "github.com/hashicorp/terraform-plugin-framework/tfsdk" - "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/vercel/terraform-provider-vercel/client" ) @@ -42,36 +40,32 @@ func (d *aliasDataSource) Configure(ctx context.Context, req datasource.Configur d.client = client } -// GetSchema returns the schema information for an alias data source -func (r *aliasDataSource) GetSchema(_ context.Context) (tfsdk.Schema, diag.Diagnostics) { - return tfsdk.Schema{ +// Schema returns the schema information for an alias data source +func (r *aliasDataSource) Schema(_ context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = schema.Schema{ Description: ` Provides information about an existing Alias resource. An Alias allows a ` + "`vercel_deployment` to be accessed through a different URL.", - Attributes: map[string]tfsdk.Attribute{ - "team_id": { + Attributes: map[string]schema.Attribute{ + "team_id": schema.StringAttribute{ Optional: true, Computed: true, - Type: types.StringType, Description: "The ID of the team the Alias and Deployment exist under.", }, - "alias": { + "alias": schema.StringAttribute{ Required: true, - Type: types.StringType, Description: "The Alias or Alias ID to be retrieved.", }, - "deployment_id": { + "deployment_id": schema.StringAttribute{ Computed: true, - Type: types.StringType, Description: "The ID of the Deployment the Alias is associated with.", }, - "id": { + "id": schema.StringAttribute{ Computed: true, - Type: types.StringType, }, }, - }, nil + } } // Read will read the alias information by requesting it from the Vercel API, and will update terraform diff --git a/vercel/data_source_file.go b/vercel/data_source_file.go index 1930fce7..05519206 100644 --- a/vercel/data_source_file.go +++ b/vercel/data_source_file.go @@ -8,8 +8,7 @@ import ( "os" "github.com/hashicorp/terraform-plugin-framework/datasource" - "github.com/hashicorp/terraform-plugin-framework/diag" - "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/vercel/terraform-provider-vercel/client" ) @@ -44,32 +43,28 @@ func (d *fileDataSource) Configure(ctx context.Context, req datasource.Configure d.client = client } -// GetSchema returns the schema information for a file data source -func (d *fileDataSource) GetSchema(_ context.Context) (tfsdk.Schema, diag.Diagnostics) { - return tfsdk.Schema{ +// Schema returns the schema information for a file data source +func (d *fileDataSource) Schema(_ context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = schema.Schema{ Description: ` Provides information about a file on disk. This will read a single file, providing metadata for use with a ` + "`vercel_deployment`.", - Attributes: map[string]tfsdk.Attribute{ - "path": { + Attributes: map[string]schema.Attribute{ + "path": schema.StringAttribute{ Description: "The path to the file on your filesystem. Note that the path is relative to the root of the terraform files.", Required: true, - Type: types.StringType, }, - "file": { + "file": schema.MapAttribute{ Description: "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.", Computed: true, - Type: types.MapType{ - ElemType: types.StringType, - }, + ElementType: types.StringType, }, - "id": { + "id": schema.StringAttribute{ Computed: true, - Type: types.StringType, }, }, - }, nil + } } // FileData represents the information terraform knows about a File data source diff --git a/vercel/data_source_file_test.go b/vercel/data_source_file_test.go index e3e4cba5..01834093 100644 --- a/vercel/data_source_file_test.go +++ b/vercel/data_source_file_test.go @@ -39,7 +39,6 @@ func testChecksum(n, attribute string, checksums Checksums) resource.TestCheckFu } func TestAcc_DataSourceFile(t *testing.T) { - t.Parallel() resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, diff --git a/vercel/data_source_prebuilt_project.go b/vercel/data_source_prebuilt_project.go index aca91644..46643388 100644 --- a/vercel/data_source_prebuilt_project.go +++ b/vercel/data_source_prebuilt_project.go @@ -10,8 +10,7 @@ import ( "path/filepath" "github.com/hashicorp/terraform-plugin-framework/datasource" - "github.com/hashicorp/terraform-plugin-framework/diag" - "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/vercel/terraform-provider-vercel/client" "github.com/vercel/terraform-provider-vercel/file" @@ -47,9 +46,9 @@ func (d *prebuiltProjectDataSource) Configure(ctx context.Context, req datasourc d.client = client } -// GetSchema returns the schema information for a project directory data source -func (d *prebuiltProjectDataSource) GetSchema(_ context.Context) (tfsdk.Schema, diag.Diagnostics) { - return tfsdk.Schema{ +// Schema returns the schema information for a project directory data source +func (d *prebuiltProjectDataSource) Schema(_ context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = schema.Schema{ Description: ` Provides the output of a project built via ` + "`vercel build`" + ` and provides metadata for use with a ` + "`vercel_deployment`" + ` @@ -58,25 +57,21 @@ Build artifacts are placed into the ` + "`.vercel/output`" + ` directory accordi This allows a Vercel Deployment to be created without sharing the Project's source code with Vercel. `, - Attributes: map[string]tfsdk.Attribute{ - "path": { + Attributes: map[string]schema.Attribute{ + "path": schema.StringAttribute{ Description: "The path to the project. Note that this path is relative to the root of your terraform files. This should be the directory that contains the `.vercel/output` directory.", Required: true, - Type: types.StringType, }, - "id": { + "id": schema.StringAttribute{ Computed: true, - Type: types.StringType, }, - "output": { + "output": schema.MapAttribute{ Description: "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.", Computed: true, - Type: types.MapType{ - ElemType: types.StringType, - }, + ElementType: types.StringType, }, }, - }, nil + } } // PrebuiltProjectData represents the information terraform knows about a project directory data source diff --git a/vercel/data_source_prebuilt_project_test.go b/vercel/data_source_prebuilt_project_test.go index c5722c16..99041db6 100644 --- a/vercel/data_source_prebuilt_project_test.go +++ b/vercel/data_source_prebuilt_project_test.go @@ -10,7 +10,6 @@ import ( ) func TestAcc_DataSourcePrebuiltProject(t *testing.T) { - t.Parallel() resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, diff --git a/vercel/data_source_project.go b/vercel/data_source_project.go index b6a6a3a0..7272ae7d 100644 --- a/vercel/data_source_project.go +++ b/vercel/data_source_project.go @@ -6,8 +6,8 @@ import ( "regexp" "github.com/hashicorp/terraform-plugin-framework/datasource" - "github.com/hashicorp/terraform-plugin-framework/diag" - "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/vercel/terraform-provider-vercel/client" @@ -43,9 +43,9 @@ func (d *projectDataSource) Configure(ctx context.Context, req datasource.Config d.client = client } -// GetSchema returns the schema information for a project data source -func (d *projectDataSource) GetSchema(_ context.Context) (tfsdk.Schema, diag.Diagnostics) { - return tfsdk.Schema{ +// Schema returns the schema information for a project data source +func (d *projectDataSource) Schema(_ context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = schema.Schema{ Description: ` Provides information about an existing project within Vercel. @@ -53,17 +53,15 @@ A Project groups deployments and custom domains. To deploy on Vercel, you need a For more detailed information, please see the [Vercel documentation](https://vercel.com/docs/concepts/projects/overview). `, - Attributes: map[string]tfsdk.Attribute{ - "team_id": { + Attributes: map[string]schema.Attribute{ + "team_id": schema.StringAttribute{ Optional: true, Computed: true, - Type: types.StringType, Description: "The team ID the project exists beneath.", }, - "name": { + "name": schema.StringAttribute{ Required: true, - Type: types.StringType, - Validators: []tfsdk.AttributeValidator{ + Validators: []validator.String{ stringLengthBetween(1, 52), stringRegex( regexp.MustCompile(`^[a-z0-9\-]{0,100}$`), @@ -72,114 +70,97 @@ For more detailed information, please see the [Vercel documentation](https://ver }, Description: "The name of the project.", }, - "build_command": { + "build_command": schema.StringAttribute{ Computed: true, - Type: types.StringType, Description: "The build command for this project. If omitted, this value will be automatically detected.", }, - "dev_command": { + "dev_command": schema.StringAttribute{ Computed: true, - Type: types.StringType, Description: "The dev command for this project. If omitted, this value will be automatically detected.", }, - "ignore_command": { + "ignore_command": schema.StringAttribute{ Computed: true, - Type: types.StringType, Description: "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.", }, - "serverless_function_region": { + "serverless_function_region": schema.StringAttribute{ Computed: true, - Type: types.StringType, Description: "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.", }, - "environment": { + "environment": schema.SetNestedAttribute{ Description: "A list of environment variables that should be configured for the project.", Computed: true, - Attributes: tfsdk.SetNestedAttributes(map[string]tfsdk.Attribute{ - "target": { - Description: "The environments that the environment variable should be present on. Valid targets are either `production`, `preview`, or `development`.", - Type: types.SetType{ - ElemType: types.StringType, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "target": schema.SetAttribute{ + Description: "The environments that the environment variable should be present on. Valid targets are either `production`, `preview`, or `development`.", + ElementType: types.StringType, + Computed: true, + }, + "key": schema.StringAttribute{ + Description: "The name of the environment variable.", + Computed: true, + }, + "value": schema.StringAttribute{ + Description: "The value of the environment variable.", + Computed: true, + }, + "id": schema.StringAttribute{ + Description: "The ID of the environment variable", + Computed: true, + }, + "git_branch": schema.StringAttribute{ + Description: "The git branch of the environment variable.", + Computed: true, }, - Computed: true, - }, - "key": { - Description: "The name of the environment variable.", - Type: types.StringType, - Computed: true, - }, - "value": { - Description: "The value of the environment variable.", - Type: types.StringType, - Computed: true, - }, - "id": { - Description: "The ID of the environment variable", - Type: types.StringType, - Computed: true, - }, - "git_branch": { - Description: "The git branch of the environment variable.", - Type: types.StringType, - Computed: true, }, - }), + }, }, - "framework": { + "framework": schema.StringAttribute{ Computed: true, - Type: types.StringType, Description: "The framework that is being used for this project. If omitted, no framework is selected.", }, - "git_repository": { + "git_repository": schema.SingleNestedAttribute{ Description: "The Git Repository that will be connected to the project. When this is defined, any pushes to the specified connected Git Repository will be automatically deployed. This requires the corresponding Vercel for [Github](https://vercel.com/docs/concepts/git/vercel-for-github), [Gitlab](https://vercel.com/docs/concepts/git/vercel-for-gitlab) or [Bitbucket](https://vercel.com/docs/concepts/git/vercel-for-bitbucket) plugins to be installed.", Computed: true, - Attributes: tfsdk.SingleNestedAttributes(map[string]tfsdk.Attribute{ - "type": { + Attributes: map[string]schema.Attribute{ + "type": schema.StringAttribute{ Description: "The git provider of the repository. Must be either `github`, `gitlab`, or `bitbucket`.", - Type: types.StringType, Computed: true, - Validators: []tfsdk.AttributeValidator{ + Validators: []validator.String{ stringOneOf("github", "gitlab", "bitbucket"), }, }, - "repo": { + "repo": schema.StringAttribute{ Description: "The name of the git repository. For example: `vercel/next.js`.", - Type: types.StringType, Computed: true, }, - "production_branch": { + "production_branch": schema.StringAttribute{ Description: "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.", - Type: types.StringType, Computed: true, }, - }), + }, }, - "id": { + "id": schema.StringAttribute{ Computed: true, - Type: types.StringType, }, - "install_command": { + "install_command": schema.StringAttribute{ Computed: true, - Type: types.StringType, Description: "The install command for this project. If omitted, this value will be automatically detected.", }, - "output_directory": { + "output_directory": schema.StringAttribute{ Computed: true, - Type: types.StringType, Description: "The output directory of the project. When null is used this value will be automatically detected.", }, - "public_source": { + "public_source": schema.BoolAttribute{ Computed: true, - Type: types.BoolType, Description: "Specifies whether the source code and logs of the deployments for this project should be public or not.", }, - "root_directory": { + "root_directory": schema.StringAttribute{ Computed: true, - Type: types.StringType, Description: "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.", }, }, - }, nil + } } // Read will read project information by requesting it from the Vercel API, and will update terraform diff --git a/vercel/data_source_project_directory.go b/vercel/data_source_project_directory.go index 5ce15890..d173fbad 100644 --- a/vercel/data_source_project_directory.go +++ b/vercel/data_source_project_directory.go @@ -8,8 +8,7 @@ import ( "os" "github.com/hashicorp/terraform-plugin-framework/datasource" - "github.com/hashicorp/terraform-plugin-framework/diag" - "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/vercel/terraform-provider-vercel/client" "github.com/vercel/terraform-provider-vercel/file" @@ -45,9 +44,9 @@ func (d *projectDirectoryDataSource) Configure(ctx context.Context, req datasour d.client = client } -// GetSchema returns the schema information for a project directory data source -func (d projectDirectoryDataSource) GetSchema(_ context.Context) (tfsdk.Schema, diag.Diagnostics) { - return tfsdk.Schema{ +// Schema returns the schema information for a project directory data source +func (d projectDirectoryDataSource) Schema(_ context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = schema.Schema{ Description: ` Provides information about files within a directory on disk. @@ -55,25 +54,21 @@ This will recursively read files, providing metadata for use with a ` + "`vercel -> If you want to prevent files from being included, this can be done with a [vercelignore file](https://vercel.com/guides/prevent-uploading-sourcepaths-with-vercelignore). `, - Attributes: map[string]tfsdk.Attribute{ - "path": { + Attributes: map[string]schema.Attribute{ + "path": schema.StringAttribute{ Description: "The path to the directory on your filesystem. Note that the path is relative to the root of the terraform files.", Required: true, - Type: types.StringType, }, - "id": { + "id": schema.StringAttribute{ Computed: true, - Type: types.StringType, }, - "files": { + "files": schema.MapAttribute{ Description: "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.", Computed: true, - Type: types.MapType{ - ElemType: types.StringType, - }, + ElementType: types.StringType, }, }, - }, nil + } } // ProjectDirectoryData represents the information terraform knows about a project directory data source diff --git a/vercel/data_source_project_directory_test.go b/vercel/data_source_project_directory_test.go index 4f3cad60..fdefa19b 100644 --- a/vercel/data_source_project_directory_test.go +++ b/vercel/data_source_project_directory_test.go @@ -8,7 +8,6 @@ import ( ) func TestAcc_DataSourceProjectDirectory(t *testing.T) { - t.Parallel() resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, diff --git a/vercel/data_source_project_test.go b/vercel/data_source_project_test.go index 690815fc..afcadca7 100644 --- a/vercel/data_source_project_test.go +++ b/vercel/data_source_project_test.go @@ -9,7 +9,6 @@ import ( ) func TestAcc_ProjectDataSource(t *testing.T) { - t.Parallel() name := acctest.RandString(16) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, diff --git a/vercel/provider.go b/vercel/provider.go index 19859eda..54138633 100644 --- a/vercel/provider.go +++ b/vercel/provider.go @@ -7,10 +7,9 @@ import ( "regexp" "github.com/hashicorp/terraform-plugin-framework/datasource" - "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/provider" + "github.com/hashicorp/terraform-plugin-framework/provider/schema" "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/tfsdk" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/vercel/terraform-provider-vercel/client" ) @@ -26,29 +25,27 @@ func (p *vercelProvider) Metadata(ctx context.Context, req provider.MetadataRequ resp.TypeName = "vercel" } -// GetSchema returns the schema information for the provider configuration itself. -func (p *vercelProvider) GetSchema(_ context.Context) (tfsdk.Schema, diag.Diagnostics) { - return tfsdk.Schema{ +// Schema returns the schema information for the provider configuration itself. +func (p *vercelProvider) Schema(_ context.Context, req provider.SchemaRequest, resp *provider.SchemaResponse) { + resp.Schema = schema.Schema{ Description: ` The Vercel provider is used to interact with resources supported by Vercel. The provider needs to be configured with the proper credentials before it can be used. Use the navigation to the left to read about the available resources. `, - Attributes: map[string]tfsdk.Attribute{ - "api_token": { - Type: types.StringType, + Attributes: map[string]schema.Attribute{ + "api_token": schema.StringAttribute{ Optional: true, Description: "The Vercel API Token to use. This can also be specified with the `VERCEL_API_TOKEN` shell environment variable. Tokens can be created from your [Vercel settings](https://vercel.com/account/tokens).", Sensitive: true, }, - "team": { - Type: types.StringType, + "team": schema.StringAttribute{ Optional: true, Description: "The default Vercel Team to use when creating resources. This can be provided as either a team slug, or team ID. The slug and ID are both available from the Team Settings page in the Vercel dashboard.", }, }, - }, nil + } } func (p *vercelProvider) Resources(_ context.Context) []func() resource.Resource { diff --git a/vercel/resource_alias.go b/vercel/resource_alias.go index 53d17016..58418263 100644 --- a/vercel/resource_alias.go +++ b/vercel/resource_alias.go @@ -4,10 +4,10 @@ import ( "context" "fmt" - "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/tfsdk" - "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/vercel/terraform-provider-vercel/client" ) @@ -42,39 +42,35 @@ func (r *aliasResource) Configure(ctx context.Context, req resource.ConfigureReq r.client = client } -// GetSchema returns the schema information for an alias resource. -func (r *aliasResource) GetSchema(_ context.Context) (tfsdk.Schema, diag.Diagnostics) { - return tfsdk.Schema{ +// Schema returns the schema information for an alias resource. +func (r *aliasResource) Schema(_ context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { + resp.Schema = schema.Schema{ Description: ` Provides an Alias resource. An Alias allows a ` + "`vercel_deployment` to be accessed through a different URL.", - Attributes: map[string]tfsdk.Attribute{ - "alias": { + Attributes: map[string]schema.Attribute{ + "alias": schema.StringAttribute{ Description: "The Alias we want to assign to the deployment defined in the URL.", Required: true, - PlanModifiers: tfsdk.AttributePlanModifiers{resource.RequiresReplace()}, - Type: types.StringType, + PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, }, - "deployment_id": { + "deployment_id": schema.StringAttribute{ Description: "The id of the Deployment the Alias should be associated with.", Required: true, - PlanModifiers: tfsdk.AttributePlanModifiers{resource.RequiresReplace()}, - Type: types.StringType, + PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, }, - "team_id": { + "team_id": schema.StringAttribute{ Optional: true, Computed: true, Description: "The ID of the team the Alias and Deployment exist under.", - PlanModifiers: tfsdk.AttributePlanModifiers{resource.RequiresReplace(), resource.UseStateForUnknown()}, - Type: types.StringType, + PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, }, - "id": { + "id": schema.StringAttribute{ Computed: true, - Type: types.StringType, }, }, - }, nil + } } // Create will create an alias within Vercel. diff --git a/vercel/resource_deployment.go b/vercel/resource_deployment.go index fe7812ba..6b5cc6d2 100644 --- a/vercel/resource_deployment.go +++ b/vercel/resource_deployment.go @@ -8,9 +8,15 @@ import ( "path/filepath" "strings" - "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/boolplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/listplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/mapplanmodifier" + "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/stringplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/vercel/terraform-provider-vercel/client" @@ -47,9 +53,9 @@ func (r *deploymentResource) Configure(ctx context.Context, req resource.Configu r.client = client } -// GetSchema returns the schema information for a deployment resource. -func (r *deploymentResource) GetSchema(_ context.Context) (tfsdk.Schema, diag.Diagnostics) { - return tfsdk.Schema{ +// Schema returns the schema information for a deployment resource. +func (r *deploymentResource) Schema(_ context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { + resp.Schema = schema.Schema{ Description: ` Provides a Deployment resource. @@ -65,124 +71,105 @@ Once the build step has completed successfully, a new, immutable deployment will deployments, you may wish to 'layer' your terraform, creating the Project with a different set of terraform to your Deployment. `, - Attributes: map[string]tfsdk.Attribute{ - "domains": { + Attributes: map[string]schema.Attribute{ + "domains": schema.ListAttribute{ Description: "A list of all the domains (default domains, staging domains and production domains) that were assigned upon deployment creation.", Computed: true, - PlanModifiers: tfsdk.AttributePlanModifiers{resource.UseStateForUnknown()}, - Type: types.ListType{ - ElemType: types.StringType, - }, + PlanModifiers: []planmodifier.List{listplanmodifier.RequiresReplace()}, + ElementType: types.StringType, }, - "environment": { + "environment": schema.MapAttribute{ Description: "A map of environment variable names to values. These are specific to a Deployment, and can also be configured on the `vercel_project` resource.", Optional: true, - PlanModifiers: tfsdk.AttributePlanModifiers{resource.RequiresReplace()}, - Type: types.MapType{ - ElemType: types.StringType, - }, + PlanModifiers: []planmodifier.Map{mapplanmodifier.RequiresReplace()}, + ElementType: types.StringType, }, - "team_id": { + "team_id": schema.StringAttribute{ Description: "The team ID to add the deployment to.", Optional: true, Computed: true, - PlanModifiers: tfsdk.AttributePlanModifiers{resource.RequiresReplace(), resource.UseStateForUnknown()}, - Type: types.StringType, + PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace(), stringplanmodifier.UseStateForUnknown()}, }, - "project_id": { + "project_id": schema.StringAttribute{ Description: "The project ID to add the deployment to.", Required: true, - PlanModifiers: tfsdk.AttributePlanModifiers{resource.RequiresReplace()}, - Type: types.StringType, + PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, }, - "id": { + "id": schema.StringAttribute{ Computed: true, - PlanModifiers: tfsdk.AttributePlanModifiers{resource.UseStateForUnknown()}, - Type: types.StringType, + PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}, }, - "path_prefix": { + "path_prefix": schema.StringAttribute{ Description: "If specified then the `path_prefix` will be stripped from the start of file paths as they are uploaded to Vercel. If this is omitted, then any leading `../`s will be stripped.", Optional: true, - Type: types.StringType, - PlanModifiers: tfsdk.AttributePlanModifiers{resource.RequiresReplace()}, + PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, }, - "url": { + "url": schema.StringAttribute{ Description: "A unique URL that is automatically generated for a deployment.", Computed: true, - PlanModifiers: tfsdk.AttributePlanModifiers{resource.UseStateForUnknown()}, - Type: types.StringType, + PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}, }, - "production": { + "production": schema.BoolAttribute{ Description: "true if the deployment is a production deployment, meaning production aliases will be assigned.", Optional: true, Computed: true, - PlanModifiers: tfsdk.AttributePlanModifiers{resource.RequiresReplace()}, - Type: types.BoolType, + PlanModifiers: []planmodifier.Bool{boolplanmodifier.RequiresReplace()}, }, - "files": { + "files": schema.MapAttribute{ Description: "A map of files to be uploaded for the deployment. This should be provided by a `vercel_project_directory` or `vercel_file` data source. Required if `git_source` is not set.", Optional: true, - PlanModifiers: tfsdk.AttributePlanModifiers{resource.RequiresReplace()}, - Type: types.MapType{ - ElemType: types.StringType, - }, - Validators: []tfsdk.AttributeValidator{ + PlanModifiers: []planmodifier.Map{mapplanmodifier.RequiresReplace()}, + ElementType: types.StringType, + Validators: []validator.Map{ mapItemsMinCount(1), }, }, - "ref": { + "ref": schema.StringAttribute{ Description: "The branch or commit hash that should be deployed. Note this will only work if the project is configured to use a Git repository. Required if `ref` is not set.", Optional: true, - PlanModifiers: tfsdk.AttributePlanModifiers{resource.RequiresReplace()}, - Type: types.StringType, + PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, }, - "project_settings": { + "project_settings": schema.SingleNestedAttribute{ Description: "Project settings that will be applied to the deployment.", Optional: true, - PlanModifiers: tfsdk.AttributePlanModifiers{resource.RequiresReplace()}, - Attributes: tfsdk.SingleNestedAttributes(map[string]tfsdk.Attribute{ - "build_command": { + PlanModifiers: []planmodifier.Object{objectplanmodifier.RequiresReplace()}, + Attributes: map[string]schema.Attribute{ + "build_command": schema.StringAttribute{ Optional: true, - PlanModifiers: tfsdk.AttributePlanModifiers{resource.RequiresReplace()}, - Type: types.StringType, + PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, Description: "The build command for this deployment. If omitted, this value will be taken from the project or automatically detected.", }, - "framework": { + "framework": schema.StringAttribute{ Optional: true, - PlanModifiers: tfsdk.AttributePlanModifiers{resource.RequiresReplace()}, - Type: types.StringType, + PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, Description: "The framework that is being used for this deployment. If omitted, no framework is selected.", - Validators: []tfsdk.AttributeValidator{ + Validators: []validator.String{ validateFramework(), }, }, - "install_command": { + "install_command": schema.StringAttribute{ Optional: true, - PlanModifiers: tfsdk.AttributePlanModifiers{resource.RequiresReplace()}, - Type: types.StringType, + PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, Description: "The install command for this deployment. If omitted, this value will be taken from the project or automatically detected.", }, - "output_directory": { + "output_directory": schema.StringAttribute{ Optional: true, - PlanModifiers: tfsdk.AttributePlanModifiers{resource.RequiresReplace()}, - Type: types.StringType, + PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, Description: "The output directory of the deployment. If omitted, this value will be taken from the project or automatically detected.", }, - "root_directory": { + "root_directory": schema.StringAttribute{ Optional: true, - PlanModifiers: tfsdk.AttributePlanModifiers{resource.RequiresReplace()}, - Type: types.StringType, + PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, Description: "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.", }, - }), + }, }, - "delete_on_destroy": { + "delete_on_destroy": schema.BoolAttribute{ Description: "Set to true to hard delete the Vercel deployment when destroying the Terraform resource. If unspecified, deployments are retained indefinitely. Note that deleted deployments are not recoverable.", Optional: true, - Type: types.BoolType, }, }, - }, nil + } } // ValidateConfig allows additional validation (specifically cross-field validation) to be added. diff --git a/vercel/resource_dns_record.go b/vercel/resource_dns_record.go index 180eb74d..7a2903d1 100644 --- a/vercel/resource_dns_record.go +++ b/vercel/resource_dns_record.go @@ -4,9 +4,11 @@ import ( "context" "fmt" - "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/vercel/terraform-provider-vercel/client" @@ -42,8 +44,8 @@ func (r *dnsRecordResource) Configure(ctx context.Context, req resource.Configur r.client = client } -func (r *dnsRecordResource) GetSchema(_ context.Context) (tfsdk.Schema, diag.Diagnostics) { - return tfsdk.Schema{ +func (r *dnsRecordResource) Schema(_ context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { + resp.Schema = schema.Schema{ Description: ` Provides a DNS Record resource. @@ -53,103 +55,91 @@ DNS records are instructions that live in authoritative DNS servers and provide For more detailed information, please see the [Vercel documentation](https://vercel.com/docs/concepts/projects/custom-domains#dns-records) `, - Attributes: map[string]tfsdk.Attribute{ - "id": { + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ Computed: true, - Type: types.StringType, }, - "team_id": { + "team_id": schema.StringAttribute{ Optional: true, Computed: true, Description: "The team ID that the domain and DNS records belong to.", - PlanModifiers: tfsdk.AttributePlanModifiers{resource.RequiresReplace(), resource.UseStateForUnknown()}, - Type: types.StringType, + PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace(), stringplanmodifier.UseStateForUnknown()}, }, - "domain": { + "domain": schema.StringAttribute{ Description: "The domain name, or zone, that the DNS record should be created beneath.", - PlanModifiers: tfsdk.AttributePlanModifiers{resource.RequiresReplace()}, + PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, Required: true, - Type: types.StringType, }, - "name": { + "name": schema.StringAttribute{ Description: "The subdomain name of the record. This should be an empty string if the rercord is for the root domain.", Required: true, - Type: types.StringType, }, - "type": { + "type": schema.StringAttribute{ Description: "The type of DNS record. Available types: " + "`A`" + ", " + "`AAAA`" + ", " + "`ALIAS`" + ", " + "`CAA`" + ", " + "`CNAME`" + ", " + "`MX`" + ", " + "`NS`" + ", " + "`SRV`" + ", " + "`TXT`" + ".", - PlanModifiers: tfsdk.AttributePlanModifiers{resource.RequiresReplace()}, + PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, Required: true, - Type: types.StringType, - Validators: []tfsdk.AttributeValidator{ + Validators: []validator.String{ stringOneOf("A", "AAAA", "ALIAS", "CAA", "CNAME", "MX", "NS", "SRV", "TXT"), }, }, - "value": { + "value": schema.StringAttribute{ // required if any record type apart from SRV. Description: "The value of the DNS record. The format depends on the 'type' property.\nFor an 'A' record, this should be a valid IPv4 address.\nFor an 'AAAA' record, this should be an IPv6 address.\nFor 'ALIAS' records, this should be a hostname.\nFor 'CAA' records, this should specify specify which Certificate Authorities (CAs) are allowed to issue certificates for the domain.\nFor 'CNAME' records, this should be a different domain name.\nFor 'MX' records, this should specify the mail server responsible for accepting messages on behalf of the domain name.\nFor 'TXT' records, this can contain arbitrary text.", Optional: true, - Type: types.StringType, }, - "ttl": { + "ttl": schema.Int64Attribute{ Description: "The TTL value in seconds. Must be a number between 60 and 2147483647. If unspecified, it will default to 60 seconds.", Optional: true, Computed: true, - Type: types.Int64Type, - Validators: []tfsdk.AttributeValidator{ + Validators: []validator.Int64{ int64GreaterThan(60), int64LessThan(2147483647), }, }, - "mx_priority": { + "mx_priority": schema.Int64Attribute{ Description: "The priority of the MX record. The priority specifies the sequence that an email server receives emails. A smaller value indicates a higher priority.", Optional: true, // required for MX records. - Type: types.Int64Type, - Validators: []tfsdk.AttributeValidator{ + Validators: []validator.Int64{ int64GreaterThan(0), int64LessThan(65535), }, }, - "srv": { + "srv": schema.SingleNestedAttribute{ Description: "Settings for an SRV record.", Optional: true, // required for SRV records. - Attributes: tfsdk.SingleNestedAttributes(map[string]tfsdk.Attribute{ - "weight": { + Attributes: map[string]schema.Attribute{ + "weight": schema.Int64Attribute{ Description: "A relative weight for records with the same priority, higher value means higher chance of getting picked.", - Type: types.Int64Type, Required: true, - Validators: []tfsdk.AttributeValidator{ + Validators: []validator.Int64{ int64GreaterThan(0), int64LessThan(65535), }, }, - "port": { + "port": schema.Int64Attribute{ Description: "The TCP or UDP port on which the service is to be found.", - Type: types.Int64Type, Required: true, - Validators: []tfsdk.AttributeValidator{ + Validators: []validator.Int64{ int64GreaterThan(0), int64LessThan(65535), }, }, - "priority": { + "priority": schema.Int64Attribute{ Description: "The priority of the target host, lower value means more preferred.", - Type: types.Int64Type, Required: true, - Validators: []tfsdk.AttributeValidator{ + Validators: []validator.Int64{ int64GreaterThan(0), int64LessThan(65535), }, }, - "target": { + "target": schema.StringAttribute{ Description: "The canonical hostname of the machine providing the service, ending in a dot.", - Type: types.StringType, Required: true, }, - }), + }, }, }, - }, nil + } } // ValidateConfig validates the Resource configuration. diff --git a/vercel/resource_dns_record_test.go b/vercel/resource_dns_record_test.go index 04e9a1d7..bab1e3db 100644 --- a/vercel/resource_dns_record_test.go +++ b/vercel/resource_dns_record_test.go @@ -52,7 +52,6 @@ func testAccDNSRecordExists(n, teamID string) resource.TestCheckFunc { } func TestAcc_DNSRecord(t *testing.T) { - t.Parallel() nameSuffix := acctest.RandString(16) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, diff --git a/vercel/resource_project.go b/vercel/resource_project.go index d78bae09..28ce7ec3 100644 --- a/vercel/resource_project.go +++ b/vercel/resource_project.go @@ -6,9 +6,11 @@ import ( "regexp" "strings" - "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/vercel/terraform-provider-vercel/client" @@ -44,9 +46,9 @@ func (r *projectResource) Configure(ctx context.Context, req resource.ConfigureR r.client = client } -// GetSchema returns the schema information for a deployment resource. -func (r *projectResource) GetSchema(_ context.Context) (tfsdk.Schema, diag.Diagnostics) { - return tfsdk.Schema{ +// Schema returns the schema information for a deployment resource. +func (r *projectResource) Schema(_ context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { + resp.Schema = schema.Schema{ Description: ` Provides a Project resource. @@ -57,18 +59,16 @@ For more detailed information, please see the [Vercel documentation](https://ver ~> Terraform currently provides both a standalone Project Environment Variable resource (a single Environment Variable), and a Project resource with Environment Variables defined in-line via the ` + "`environment` field" + `. At this time you cannot use a Vercel Project resource with in-line ` + "`environment` in conjunction with any `vercel_project_environment_variable`" + ` resources. Doing so will cause a conflict of settings and will overwrite Environment Variables. `, - Attributes: map[string]tfsdk.Attribute{ - "team_id": { + Attributes: map[string]schema.Attribute{ + "team_id": schema.StringAttribute{ Optional: true, Computed: true, - Type: types.StringType, - PlanModifiers: tfsdk.AttributePlanModifiers{resource.RequiresReplace(), resource.UseStateForUnknown()}, + PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace(), stringplanmodifier.UseStateForUnknown()}, Description: "The team ID to add the project to.", }, - "name": { + "name": schema.StringAttribute{ Required: true, - Type: types.StringType, - Validators: []tfsdk.AttributeValidator{ + Validators: []validator.String{ stringLengthBetween(1, 52), stringRegex( regexp.MustCompile(`^[a-z0-9\-]{0,100}$`), @@ -77,129 +77,112 @@ At this time you cannot use a Vercel Project resource with in-line ` + "`environ }, Description: "The desired name for the project.", }, - "build_command": { + "build_command": schema.StringAttribute{ Optional: true, - Type: types.StringType, Description: "The build command for this project. If omitted, this value will be automatically detected.", }, - "dev_command": { + "dev_command": schema.StringAttribute{ Optional: true, - Type: types.StringType, Description: "The dev command for this project. If omitted, this value will be automatically detected.", }, - "ignore_command": { + "ignore_command": schema.StringAttribute{ Optional: true, - Type: types.StringType, Description: "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.", }, - "serverless_function_region": { + "serverless_function_region": schema.StringAttribute{ Optional: true, Computed: true, - Type: types.StringType, Description: "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.", - Validators: []tfsdk.AttributeValidator{ + Validators: []validator.String{ validateServerlessFunctionRegion(), }, }, - "environment": { + "environment": schema.SetNestedAttribute{ Description: "A set of Environment Variables that should be configured for the project.", Optional: true, - Attributes: tfsdk.SetNestedAttributes(map[string]tfsdk.Attribute{ - "target": { - Description: "The environments that the Environment Variable should be present on. Valid targets are either `production`, `preview`, or `development`.", - Type: types.SetType{ - ElemType: types.StringType, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "target": schema.SetAttribute{ + Description: "The environments that the Environment Variable should be present on. Valid targets are either `production`, `preview`, or `development`.", + ElementType: types.StringType, + Validators: []validator.Set{ + stringSetItemsIn("production", "preview", "development"), + }, + Required: true, }, - Validators: []tfsdk.AttributeValidator{ - stringSetItemsIn("production", "preview", "development"), + "git_branch": schema.StringAttribute{ + Description: "The git branch of the Environment Variable.", + Optional: true, + }, + "key": schema.StringAttribute{ + Description: "The name of the Environment Variable.", + Required: true, + }, + "value": schema.StringAttribute{ + Description: "The value of the Environment Variable.", + Required: true, + Sensitive: true, + }, + "id": schema.StringAttribute{ + Description: "The ID of the Environment Variable.", + Computed: true, }, - Required: true, - }, - "git_branch": { - Description: "The git branch of the Environment Variable.", - Type: types.StringType, - Optional: true, - }, - "key": { - Description: "The name of the Environment Variable.", - Type: types.StringType, - Required: true, - }, - "value": { - Description: "The value of the Environment Variable.", - Type: types.StringType, - Required: true, - Sensitive: true, - }, - "id": { - Description: "The ID of the Environment Variable.", - Type: types.StringType, - Computed: true, }, - }), + }, }, - "framework": { + "framework": schema.StringAttribute{ Optional: true, - Type: types.StringType, Description: "The framework that is being used for this project. If omitted, no framework is selected.", - Validators: []tfsdk.AttributeValidator{ + Validators: []validator.String{ validateFramework(), }, }, - "git_repository": { + "git_repository": schema.SingleNestedAttribute{ Description: "The Git Repository that will be connected to the project. When this is defined, any pushes to the specified connected Git Repository will be automatically deployed. This requires the corresponding Vercel for [Github](https://vercel.com/docs/concepts/git/vercel-for-github), [Gitlab](https://vercel.com/docs/concepts/git/vercel-for-gitlab) or [Bitbucket](https://vercel.com/docs/concepts/git/vercel-for-bitbucket) plugins to be installed.", Optional: true, - Attributes: tfsdk.SingleNestedAttributes(map[string]tfsdk.Attribute{ - "type": { + Attributes: map[string]schema.Attribute{ + "type": schema.StringAttribute{ Description: "The git provider of the repository. Must be either `github`, `gitlab`, or `bitbucket`.", - Type: types.StringType, Required: true, - Validators: []tfsdk.AttributeValidator{ + Validators: []validator.String{ stringOneOf("github", "gitlab", "bitbucket"), }, - PlanModifiers: tfsdk.AttributePlanModifiers{resource.RequiresReplace()}, + PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, }, - "repo": { + "repo": schema.StringAttribute{ Description: "The name of the git repository. For example: `vercel/next.js`.", - Type: types.StringType, Required: true, - PlanModifiers: tfsdk.AttributePlanModifiers{resource.RequiresReplace()}, + PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, }, - "production_branch": { + "production_branch": schema.StringAttribute{ Description: "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.", - Type: types.StringType, Optional: true, Computed: true, }, - }), + }, }, - "id": { + "id": schema.StringAttribute{ Computed: true, - Type: types.StringType, - PlanModifiers: tfsdk.AttributePlanModifiers{resource.UseStateForUnknown()}, + PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}, }, - "install_command": { + "install_command": schema.StringAttribute{ Optional: true, - Type: types.StringType, Description: "The install command for this project. If omitted, this value will be automatically detected.", }, - "output_directory": { + "output_directory": schema.StringAttribute{ Optional: true, - Type: types.StringType, Description: "The output directory of the project. If omitted, this value will be automatically detected.", }, - "public_source": { + "public_source": schema.BoolAttribute{ Optional: true, - Type: types.BoolType, Description: "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": { + "root_directory": schema.StringAttribute{ Optional: true, - Type: types.StringType, Description: "The name of a directory or relative path to the source code of your project. If omitted, it will default to the project root.", }, }, - }, nil + } } // Create will create a project within Vercel by calling the Vercel API. diff --git a/vercel/resource_project_domain.go b/vercel/resource_project_domain.go index 8646bdad..45e1e635 100644 --- a/vercel/resource_project_domain.go +++ b/vercel/resource_project_domain.go @@ -5,10 +5,11 @@ import ( "fmt" "strings" - "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/tfsdk" - "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/vercel/terraform-provider-vercel/client" ) @@ -43,60 +44,53 @@ func (r *projectDomainResource) Configure(ctx context.Context, req resource.Conf r.client = client } -// GetSchema returns the schema information for a deployment resource. -func (r *projectDomainResource) GetSchema(context.Context) (tfsdk.Schema, diag.Diagnostics) { - return tfsdk.Schema{ +// Schema returns the schema information for a deployment resource. +func (r *projectDomainResource) Schema(_ context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { + resp.Schema = schema.Schema{ Description: ` Provides a Project Domain resource. A Project Domain is used to associate a domain name with a ` + "`vercel_project`." + ` By default, Project Domains will be automatically applied to any ` + "`production` deployments.", - Attributes: map[string]tfsdk.Attribute{ - "project_id": { + Attributes: map[string]schema.Attribute{ + "project_id": schema.StringAttribute{ Description: "The project ID to add the deployment to.", Required: true, - PlanModifiers: tfsdk.AttributePlanModifiers{resource.RequiresReplace()}, - Type: types.StringType, + PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, }, - "team_id": { + "team_id": schema.StringAttribute{ Optional: true, Computed: true, - PlanModifiers: tfsdk.AttributePlanModifiers{resource.RequiresReplace(), resource.UseStateForUnknown()}, - Type: types.StringType, + PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace(), stringplanmodifier.UseStateForUnknown()}, Description: "The ID of the team the project exists under.", }, - "id": { + "id": schema.StringAttribute{ Computed: true, - PlanModifiers: tfsdk.AttributePlanModifiers{resource.UseStateForUnknown()}, - Type: types.StringType, + PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}, }, - "domain": { + "domain": schema.StringAttribute{ Description: "The domain name to associate with the project.", Required: true, - PlanModifiers: tfsdk.AttributePlanModifiers{resource.RequiresReplace()}, - Type: types.StringType, + PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, }, - "redirect": { + "redirect": schema.StringAttribute{ Description: "The domain name that serves as a target destination for redirects.", Optional: true, - Type: types.StringType, }, - "redirect_status_code": { + "redirect_status_code": schema.Int64Attribute{ Description: "The HTTP status code to use when serving as a redirect.", Optional: true, - Type: types.Int64Type, - Validators: []tfsdk.AttributeValidator{ + Validators: []validator.Int64{ int64OneOf(301, 302, 307, 308), }, }, - "git_branch": { + "git_branch": schema.StringAttribute{ Description: "Git branch to link to the project domain. Deployments from this git branch will be assigned the domain name.", Optional: true, - Type: types.StringType, }, }, - }, nil + } } // Create will create a project domain within Vercel. diff --git a/vercel/resource_project_environment_variable.go b/vercel/resource_project_environment_variable.go index 393a0f0b..971d83c9 100644 --- a/vercel/resource_project_environment_variable.go +++ b/vercel/resource_project_environment_variable.go @@ -5,9 +5,10 @@ import ( "fmt" "strings" - "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/vercel/terraform-provider-vercel/client" @@ -43,9 +44,9 @@ func (r *projectEnvironmentVariableResource) Configure(ctx context.Context, req r.client = client } -// GetSchema returns the schema information for a project environment variable resource. -func (r *projectEnvironmentVariableResource) GetSchema(_ context.Context) (tfsdk.Schema, diag.Diagnostics) { - return tfsdk.Schema{ +// Schema returns the schema information for a project environment variable resource. +func (r *projectEnvironmentVariableResource) Schema(_ context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { + resp.Schema = schema.Schema{ Description: ` Provides a Project Environment Variable resource. @@ -56,52 +57,44 @@ For more detailed information, please see the [Vercel documentation](https://ver ~> Terraform currently provides both a standalone Project Environment Variable resource (a single Environment Variable), and a Project resource with Environment Variables defined in-line via the ` + "`environment` field" + `. At this time you cannot use a Vercel Project resource with in-line ` + "`environment` in conjunction with any `vercel_project_environment_variable`" + ` resources. Doing so will cause a conflict of settings and will overwrite Environment Variables. `, - Attributes: map[string]tfsdk.Attribute{ - "target": { + Attributes: map[string]schema.Attribute{ + "target": schema.SetAttribute{ Required: true, Description: "The environments that the Environment Variable should be present on. Valid targets are either `production`, `preview`, or `development`.", - Type: types.SetType{ - ElemType: types.StringType, - }, + ElementType: types.StringType, }, - "key": { + "key": schema.StringAttribute{ Required: true, - PlanModifiers: tfsdk.AttributePlanModifiers{resource.RequiresReplace()}, + PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, Description: "The name of the Environment Variable.", - Type: types.StringType, }, - "value": { + "value": schema.StringAttribute{ Required: true, Description: "The value of the Environment Variable.", - Type: types.StringType, Sensitive: true, }, - "git_branch": { + "git_branch": schema.StringAttribute{ Optional: true, Description: "The git branch of the Environment Variable.", - Type: types.StringType, }, - "project_id": { + "project_id": schema.StringAttribute{ Required: true, Description: "The ID of the Vercel project.", - PlanModifiers: tfsdk.AttributePlanModifiers{resource.RequiresReplace()}, - Type: types.StringType, + PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, }, - "team_id": { + "team_id": schema.StringAttribute{ Optional: true, Computed: true, Description: "The ID of the Vercel team.", - PlanModifiers: tfsdk.AttributePlanModifiers{resource.RequiresReplace(), resource.UseStateForUnknown()}, - Type: types.StringType, + PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace(), stringplanmodifier.UseStateForUnknown()}, }, - "id": { + "id": schema.StringAttribute{ Description: "The ID of the Environment Variable.", - Type: types.StringType, - PlanModifiers: tfsdk.AttributePlanModifiers{resource.UseStateForUnknown()}, + PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace(), stringplanmodifier.UseStateForUnknown()}, Computed: true, }, }, - }, nil + } } // Create will create a new project environment variable for a Vercel project. diff --git a/vercel/validator_framework.go b/vercel/validator_framework.go index e3975aa2..005f2d99 100644 --- a/vercel/validator_framework.go +++ b/vercel/validator_framework.go @@ -8,8 +8,7 @@ import ( "net/http" "strings" - "github.com/hashicorp/terraform-plugin-framework/tfsdk" - "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" ) func validateFramework() validatorFramework { @@ -34,11 +33,15 @@ func (v validatorFramework) MarkdownDescription(ctx context.Context) string { return fmt.Sprintf("The framework provided is not supported on Vercel. Must be one of `%s`.", strings.Join(keys(v.frameworks), "`, `")) } -func (v validatorFramework) Validate(ctx context.Context, req tfsdk.ValidateAttributeRequest, resp *tfsdk.ValidateAttributeResponse) { +func (v validatorFramework) ValidateString(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) { + if req.ConfigValue.IsUnknown() || req.ConfigValue.IsNull() { + return + } + apires, err := http.Get("https://api-frameworks.zeit.sh/") if err != nil { resp.Diagnostics.AddAttributeError( - req.AttributePath, + req.Path, "Unable to validate attribute", fmt.Sprintf("Unable to retrieve Vercel frameworks: unexpected error: %s", err), ) @@ -46,7 +49,7 @@ func (v validatorFramework) Validate(ctx context.Context, req tfsdk.ValidateAttr } if apires.StatusCode != 200 { resp.Diagnostics.AddAttributeError( - req.AttributePath, + req.Path, "Unable to validate attribute", fmt.Sprintf("Unable to retrieve Vercel frameworks: unexpected status code: %d", apires.StatusCode), ) @@ -57,7 +60,7 @@ func (v validatorFramework) Validate(ctx context.Context, req tfsdk.ValidateAttr responseBody, err := io.ReadAll(apires.Body) if err != nil { resp.Diagnostics.AddAttributeError( - req.AttributePath, + req.Path, "Unable to validate attribute", fmt.Sprintf("Unable to retrieve Vercel frameworks: error reading response body: %s", err), ) @@ -69,7 +72,7 @@ func (v validatorFramework) Validate(ctx context.Context, req tfsdk.ValidateAttr err = json.Unmarshal(responseBody, &fwList) if err != nil { resp.Diagnostics.AddAttributeError( - req.AttributePath, + req.Path, "Unable to validate attribute", fmt.Sprintf("Unable to retrieve Vercel frameworks: error parsing frameworks response: %s", err), ) @@ -82,21 +85,15 @@ func (v validatorFramework) Validate(ctx context.Context, req tfsdk.ValidateAttr v.frameworks[fw.Slug] = struct{}{} } - var item types.String - diags := tfsdk.ValueAs(ctx, req.AttributeConfig, &item) - resp.Diagnostics.Append(diags...) - if diags.HasError() { - return - } - if item.IsUnknown() || item.IsNull() { + if req.ConfigValue.IsUnknown() || req.ConfigValue.IsNull() { return } - if _, ok := v.frameworks[item.ValueString()]; !ok { + if _, ok := v.frameworks[req.ConfigValue.ValueString()]; !ok { resp.Diagnostics.AddAttributeError( - req.AttributePath, + req.Path, "Invalid Framework", - fmt.Sprintf("The framework %s is not supported on Vercel. Must be one of %s.", item.ValueString(), strings.Join(keys(v.frameworks), ", ")), + fmt.Sprintf("The framework %s is not supported on Vercel. Must be one of %s.", req.ConfigValue.ValueString(), strings.Join(keys(v.frameworks), ", ")), ) return } diff --git a/vercel/validator_int64_greater_than.go b/vercel/validator_int64_greater_than.go index adb18804..51fa5db4 100644 --- a/vercel/validator_int64_greater_than.go +++ b/vercel/validator_int64_greater_than.go @@ -4,8 +4,7 @@ import ( "context" "fmt" - "github.com/hashicorp/terraform-plugin-framework/tfsdk" - "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" ) func int64GreaterThan(val int64) validatorInt64GreaterThan { @@ -25,22 +24,16 @@ func (v validatorInt64GreaterThan) MarkdownDescription(ctx context.Context) stri return fmt.Sprintf("Value must be greater than `%d`", v.Min) } -func (v validatorInt64GreaterThan) Validate(ctx context.Context, req tfsdk.ValidateAttributeRequest, resp *tfsdk.ValidateAttributeResponse) { - var item types.Int64 - diags := tfsdk.ValueAs(ctx, req.AttributeConfig, &item) - resp.Diagnostics.Append(diags...) - if diags.HasError() { - return - } - if item.IsUnknown() || item.IsNull() { +func (v validatorInt64GreaterThan) ValidateInt64(ctx context.Context, req validator.Int64Request, resp *validator.Int64Response) { + if req.ConfigValue.IsUnknown() || req.ConfigValue.IsNull() { return } - if item.ValueInt64() < v.Min { + if req.ConfigValue.ValueInt64() < v.Min { resp.Diagnostics.AddAttributeError( - req.AttributePath, + req.Path, "Invalid value provided", - fmt.Sprintf("Value must be greater than %d, got: %d.", v.Min, item.ValueInt64()), + fmt.Sprintf("Value must be greater than %d, got: %d.", v.Min, req.ConfigValue.ValueInt64()), ) return } diff --git a/vercel/validator_int64_less_than.go b/vercel/validator_int64_less_than.go index 8fa6da05..5419f27b 100644 --- a/vercel/validator_int64_less_than.go +++ b/vercel/validator_int64_less_than.go @@ -4,8 +4,7 @@ import ( "context" "fmt" - "github.com/hashicorp/terraform-plugin-framework/tfsdk" - "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" ) func int64LessThan(val int64) validatorInt64LessThan { @@ -25,22 +24,16 @@ func (v validatorInt64LessThan) MarkdownDescription(ctx context.Context) string return fmt.Sprintf("Value must be less than `%d`", v.Max) } -func (v validatorInt64LessThan) Validate(ctx context.Context, req tfsdk.ValidateAttributeRequest, resp *tfsdk.ValidateAttributeResponse) { - var item types.Int64 - diags := tfsdk.ValueAs(ctx, req.AttributeConfig, &item) - resp.Diagnostics.Append(diags...) - if diags.HasError() { - return - } - if item.IsUnknown() || item.IsNull() { +func (v validatorInt64LessThan) ValidateInt64(ctx context.Context, req validator.Int64Request, resp *validator.Int64Response) { + if req.ConfigValue.IsUnknown() || req.ConfigValue.IsNull() { return } - if item.ValueInt64() > v.Max { + if req.ConfigValue.ValueInt64() > v.Max { resp.Diagnostics.AddAttributeError( - req.AttributePath, + req.Path, "Invalid value provided", - fmt.Sprintf("Value must be less than %d, got: %d.", v.Max, item.ValueInt64()), + fmt.Sprintf("Value must be less than %d, got: %d.", v.Max, req.ConfigValue.ValueInt64()), ) return } diff --git a/vercel/validator_int64_one_of.go b/vercel/validator_int64_one_of.go index 70ef30e4..fdc9e67b 100644 --- a/vercel/validator_int64_one_of.go +++ b/vercel/validator_int64_one_of.go @@ -6,8 +6,7 @@ import ( "strconv" "strings" - "github.com/hashicorp/terraform-plugin-framework/tfsdk" - "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" ) func int64OneOf(items ...int64) validatorInt64OneOf { @@ -38,22 +37,16 @@ func (v validatorInt64OneOf) MarkdownDescription(ctx context.Context) string { return fmt.Sprintf("Item must be one of `%s`", strings.Join(v.keys(), "` `")) } -func (v validatorInt64OneOf) Validate(ctx context.Context, req tfsdk.ValidateAttributeRequest, resp *tfsdk.ValidateAttributeResponse) { - var item types.Int64 - diags := tfsdk.ValueAs(ctx, req.AttributeConfig, &item) - resp.Diagnostics.Append(diags...) - if diags.HasError() { - return - } - if item.IsUnknown() || item.IsNull() { +func (v validatorInt64OneOf) ValidateInt64(ctx context.Context, req validator.Int64Request, resp *validator.Int64Response) { + if req.ConfigValue.IsUnknown() || req.ConfigValue.IsNull() { return } - if _, ok := v.Items[item.ValueInt64()]; !ok { + if _, ok := v.Items[req.ConfigValue.ValueInt64()]; !ok { resp.Diagnostics.AddAttributeError( - req.AttributePath, + req.Path, "Invalid value provided", - fmt.Sprintf("Item must be one of %s, got: %d.", strings.Join(v.keys(), " "), item.ValueInt64()), + fmt.Sprintf("Item must be one of %s, got: %d.", strings.Join(v.keys(), " "), req.ConfigValue.ValueInt64()), ) return } diff --git a/vercel/validator_map_items_min_count.go b/vercel/validator_map_items_min_count.go index b33e7691..be3f1b5b 100644 --- a/vercel/validator_map_items_min_count.go +++ b/vercel/validator_map_items_min_count.go @@ -4,8 +4,7 @@ import ( "context" "fmt" - "github.com/hashicorp/terraform-plugin-framework/tfsdk" - "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" ) func mapItemsMinCount(minCount int) validatorMapItemsMinCount { @@ -26,20 +25,14 @@ func (v validatorMapItemsMinCount) MarkdownDescription(ctx context.Context) stri return fmt.Sprintf("Map must contain at least `%d` item(s)", v.Min) } -func (v validatorMapItemsMinCount) Validate(ctx context.Context, req tfsdk.ValidateAttributeRequest, resp *tfsdk.ValidateAttributeResponse) { - var val types.Map - diags := tfsdk.ValueAs(ctx, req.AttributeConfig, &val) - resp.Diagnostics.Append(diags...) - if diags.HasError() { +func (v validatorMapItemsMinCount) ValidateMap(ctx context.Context, req validator.MapRequest, resp *validator.MapResponse) { + if req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() { return } - if val.IsNull() || val.IsUnknown() { - return - } - count := len(val.Elements()) + count := len(req.ConfigValue.Elements()) if count < v.Min { resp.Diagnostics.AddAttributeError( - req.AttributePath, + req.Path, "Invalid value provided", fmt.Sprintf( "Map must contain at least %d items, got: %d.", diff --git a/vercel/validator_serverless_function_region.go b/vercel/validator_serverless_function_region.go index 689340b9..a6767d6c 100644 --- a/vercel/validator_serverless_function_region.go +++ b/vercel/validator_serverless_function_region.go @@ -8,8 +8,7 @@ import ( "net/http" "strings" - "github.com/hashicorp/terraform-plugin-framework/tfsdk" - "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" ) func validateServerlessFunctionRegion() validatorServerlessFunctionRegion { @@ -50,11 +49,14 @@ func keys(v map[string]struct{}) (out []string) { return } -func (v validatorServerlessFunctionRegion) Validate(ctx context.Context, req tfsdk.ValidateAttributeRequest, resp *tfsdk.ValidateAttributeResponse) { +func (v validatorServerlessFunctionRegion) ValidateString(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) { + if req.ConfigValue.IsUnknown() || req.ConfigValue.IsNull() { + return + } apires, err := http.Get("https://dcs.vercel-infra.com") if err != nil { resp.Diagnostics.AddAttributeError( - req.AttributePath, + req.Path, "Unable to validate attribute", fmt.Sprintf("Unable to retrieve Vercel serverless function regions: unexpected error: %s", err), ) @@ -62,7 +64,7 @@ func (v validatorServerlessFunctionRegion) Validate(ctx context.Context, req tfs } if apires.StatusCode != 200 { resp.Diagnostics.AddAttributeError( - req.AttributePath, + req.Path, "Unable to validate attribute", fmt.Sprintf("Unable to retrieve Vercel serverless function regions: unexpected status code: %d", apires.StatusCode), ) @@ -73,7 +75,7 @@ func (v validatorServerlessFunctionRegion) Validate(ctx context.Context, req tfs responseBody, err := io.ReadAll(apires.Body) if err != nil { resp.Diagnostics.AddAttributeError( - req.AttributePath, + req.Path, "Unable to validate attribute", fmt.Sprintf("Unable to retrieve Vercel serverless function regions: error reading response body: %s", err), ) @@ -86,7 +88,7 @@ func (v validatorServerlessFunctionRegion) Validate(ctx context.Context, req tfs err = json.Unmarshal(responseBody, ®ions) if err != nil { resp.Diagnostics.AddAttributeError( - req.AttributePath, + req.Path, "Unable to validate attribute", fmt.Sprintf("Unable to retrieve Vercel serverless function regions: error parsing serverless function regions response: %s", err), ) @@ -102,21 +104,11 @@ func (v validatorServerlessFunctionRegion) Validate(ctx context.Context, req tfs } } - var item types.String - diags := tfsdk.ValueAs(ctx, req.AttributeConfig, &item) - resp.Diagnostics.Append(diags...) - if diags.HasError() { - return - } - if item.IsUnknown() || item.IsNull() { - return - } - - if _, ok := v.regions[item.ValueString()]; !ok { + if _, ok := v.regions[req.ConfigValue.ValueString()]; !ok { resp.Diagnostics.AddAttributeError( - req.AttributePath, + req.Path, "Invalid Serverless Function Region", - fmt.Sprintf("The serverless function region %s is not supported on Vercel. Must be one of %s.", item.ValueString(), strings.Join(keys(v.regions), ", ")), + fmt.Sprintf("The serverless function region %s is not supported on Vercel. Must be one of %s.", req.ConfigValue.ValueString(), strings.Join(keys(v.regions), ", ")), ) return } diff --git a/vercel/validator_string_length_between.go b/vercel/validator_string_length_between.go index a4417581..142e470b 100644 --- a/vercel/validator_string_length_between.go +++ b/vercel/validator_string_length_between.go @@ -4,8 +4,7 @@ import ( "context" "fmt" - "github.com/hashicorp/terraform-plugin-framework/tfsdk" - "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" ) func stringLengthBetween(minLength int, maxLength int) validatorStringLengthBetween { @@ -27,20 +26,13 @@ func (v validatorStringLengthBetween) MarkdownDescription(ctx context.Context) s return fmt.Sprintf("String length must be between `%d` and `%d`", v.Min, v.Max) } -func (v validatorStringLengthBetween) Validate(ctx context.Context, req tfsdk.ValidateAttributeRequest, resp *tfsdk.ValidateAttributeResponse) { - var str types.String - diags := tfsdk.ValueAs(ctx, req.AttributeConfig, &str) - resp.Diagnostics.Append(diags...) - if diags.HasError() { +func (v validatorStringLengthBetween) ValidateString(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) { + if req.ConfigValue.IsUnknown() || req.ConfigValue.IsNull() { return } - if str.IsUnknown() || str.IsNull() { - return - } - strLen := len(str.ValueString()) + strLen := len(req.ConfigValue.ValueString()) if strLen < v.Min || strLen > v.Max { - resp.Diagnostics.AddAttributeError( - req.AttributePath, + resp.Diagnostics.AddError( "Invalid value provided", fmt.Sprintf("String length must be between %d and %d, got: %d.", v.Min, v.Max, strLen), ) diff --git a/vercel/validator_string_one_of.go b/vercel/validator_string_one_of.go index 44974f0b..5df30c51 100644 --- a/vercel/validator_string_one_of.go +++ b/vercel/validator_string_one_of.go @@ -5,8 +5,7 @@ import ( "fmt" "strings" - "github.com/hashicorp/terraform-plugin-framework/tfsdk" - "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" ) func stringOneOf(items ...string) validatorStringOneOf { @@ -37,22 +36,16 @@ func (v validatorStringOneOf) MarkdownDescription(ctx context.Context) string { return fmt.Sprintf("Item must be one of `%s`", strings.Join(v.keys(), "` `")) } -func (v validatorStringOneOf) Validate(ctx context.Context, req tfsdk.ValidateAttributeRequest, resp *tfsdk.ValidateAttributeResponse) { - var item types.String - diags := tfsdk.ValueAs(ctx, req.AttributeConfig, &item) - resp.Diagnostics.Append(diags...) - if diags.HasError() { - return - } - if item.IsUnknown() || item.IsNull() { +func (v validatorStringOneOf) ValidateString(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) { + if req.ConfigValue.IsUnknown() || req.ConfigValue.IsNull() { return } - if _, ok := v.Items[item.ValueString()]; !ok { + if _, ok := v.Items[req.ConfigValue.ValueString()]; !ok { resp.Diagnostics.AddAttributeError( - req.AttributePath, + req.Path, "Invalid value provided", - fmt.Sprintf("Item must be one of %s, got: %s.", strings.Join(v.keys(), ", "), item.ValueString()), + fmt.Sprintf("Item must be one of %s, got: %s.", strings.Join(v.keys(), ", "), req.ConfigValue.ValueString()), ) return } diff --git a/vercel/validator_string_regex.go b/vercel/validator_string_regex.go index ba261f01..d2f56ba8 100644 --- a/vercel/validator_string_regex.go +++ b/vercel/validator_string_regex.go @@ -4,8 +4,7 @@ import ( "context" "regexp" - "github.com/hashicorp/terraform-plugin-framework/tfsdk" - "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" ) func stringRegex(re *regexp.Regexp, errorMessage string) validatorStringRegex { @@ -27,20 +26,14 @@ func (v validatorStringRegex) MarkdownDescription(ctx context.Context) string { return v.ErrorMessage } -func (v validatorStringRegex) Validate(ctx context.Context, req tfsdk.ValidateAttributeRequest, resp *tfsdk.ValidateAttributeResponse) { - var str types.String - diags := tfsdk.ValueAs(ctx, req.AttributeConfig, &str) - resp.Diagnostics.Append(diags...) - if diags.HasError() { +func (v validatorStringRegex) ValidateString(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) { + if req.ConfigValue.IsUnknown() || req.ConfigValue.IsNull() { return } - if str.IsUnknown() || str.IsNull() { - return - } - ok := v.Re.MatchString(str.ValueString()) + ok := v.Re.MatchString(req.ConfigValue.ValueString()) if !ok { resp.Diagnostics.AddAttributeError( - req.AttributePath, + req.Path, "Invalid value provided", v.ErrorMessage, ) diff --git a/vercel/validator_string_set_items_in.go b/vercel/validator_string_set_items_in.go index 525e0aee..cec172c3 100644 --- a/vercel/validator_string_set_items_in.go +++ b/vercel/validator_string_set_items_in.go @@ -5,6 +5,7 @@ import ( "fmt" "strings" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/tfsdk" "github.com/hashicorp/terraform-plugin-framework/types" ) @@ -37,30 +38,21 @@ func (v validatorStringSetItemsIn) MarkdownDescription(ctx context.Context) stri return fmt.Sprintf("Set item must be one of `%s`", strings.Join(v.keys(), ",` `")) } -func (v validatorStringSetItemsIn) Validate(ctx context.Context, req tfsdk.ValidateAttributeRequest, resp *tfsdk.ValidateAttributeResponse) { - var set types.Set - diags := tfsdk.ValueAs(ctx, req.AttributeConfig, &set) - resp.Diagnostics.Append(diags...) - if diags.HasError() { - return - } - if set.IsUnknown() || set.IsNull() { +func (v validatorStringSetItemsIn) ValidateSet(ctx context.Context, req validator.SetRequest, resp *validator.SetResponse) { + if req.ConfigValue.IsUnknown() || req.ConfigValue.IsNull() { return } - for _, i := range set.Elements() { + for _, i := range req.ConfigValue.Elements() { var item types.String diags := tfsdk.ValueAs(ctx, i, &item) resp.Diagnostics.Append(diags...) if diags.HasError() { return } - if set.IsUnknown() || set.IsNull() { - return - } if _, ok := v.Items[item.ValueString()]; !ok { resp.Diagnostics.AddAttributeError( - req.AttributePath, + req.Path, "Invalid value provided", fmt.Sprintf("%s, got %s", v.Description(ctx), item.ValueString()), )