-
Notifications
You must be signed in to change notification settings - Fork 3
Description
Terraform CLI and Framework Versions
Terraform 1.2.9
Framework 0.12.0
Use Cases or Problem Statement
Provider developers should be able to call functions that will appropriately mutate the schema for use with timeouts that are declared using nested blocks or nested attributes.
Provider developers should be able to call functions that will retrieve the appropriate time.Duration for use in CRUD functions.
Nested Blocks
Currently, timeouts are defined within configuration when using SDKv2 as follows:
resource "provider_resource" "example" {
/* ... */
timeouts {
create = "60m"
read = "10m"
}
}When using the Framework, this would require that the tfsdk.Schema for the resource be manually altered by the provider developer to include the following:
func (t exampleResource) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagnostics) {
return tfsdk.Schema{
/* ... */
Blocks: map[string]tfsdk.Block{
"timeouts": {
Attributes: map[string]tfsdk.Attribute{
"create": {
Type: types.StringType,
Optional: true,
},
/* ... */
},
NestingMode: tfsdk.BlockNestingModeSingle,
},
},Nested Attributes
With the availability of nested attributes in protocol version 6, there is also the opportunity to define timeouts using the nested attribute syntax. For instance:
resource "provider_resource" "example" {
/* ... */
timeouts = {
create = "60m"
read = "10m"
}
}This would require that the tfsdk.Schema for the resource be manually altered by the provider developer to include the following:
diag.Diagnostics) {
return tfsdk.Schema{
/* ... */
Attributes: map[string]tfsdk.Attribute{
"timeouts": {
Optional: true,
Attributes: tfsdk.SingleNestedAttributes(map[string]tfsdk.Attribute{
"create": {
Optional: true,
Type: types.StringType,
},
/* ... */
}),
},
},Proposal
Inside a timeouts package, create the following exported types:
package timeouts
type Opts struct {
Create bool
Read bool
Update bool
Delete bool
}
func Block(ctx context.Context, opts TimeoutsOpts) tfsdk.Block {
// Each field in opts is checked and a map entry is added
// for each field that is true.
return tfsdk.Block{
Attributes: map[string]tfsdk.Attribute{
"create": {
Type: types.StringType,
Optional: true,
},
"read": {
Type: types.StringType,
Optional: true,
},
/* ... */
},
NestingMode: tfsdk.BlockNestingModeSingle,
}
}
func BlockAll(ctx context.Context) tfsdk.Block {
return TimeoutsBlock(ctx, TimeoutsOpts{
Create: true,
Read: true,
Update: true,
Delete: true,
})
}
func Attributes(ctx context.Context, opts TimeoutsOpts) tfsdk.Attribute {
// Each field in opts is checked and a map entry is added
// for each field that is true.
return tfsdk.Attribute{
Optional: true,
Attributes: tfsdk.SingleNestedAttributes(map[string]tfsdk.Attribute{
"create": {
Optional: true,
Type: types.StringType,
},
"read": {
Optional: true,
Type: types.StringType,
},
/* ... */
}),
}
}
func AttributesAll(ctx context.Context) tfsdk.Attribute {
return TimeoutsAttributes(ctx, TimeoutsOpts{
Create: true,
Read: true,
Update: true,
Delete: true,
})
}This will then allow provider developers to call these functions to generate a nested block or nested attributes as follows:
func (t exampleResourceType) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagnostics) {
return tfsdk.Schema{
Blocks: map[string]tfsdk.Block{
"timeouts": timeouts.Block(ctx, TimeoutsOpts{/* ... */}),
},
/* ... */func (t exampleResourceType) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagnostics) {
return tfsdk.Schema{
Attributes: map[string]tfsdk.Attribute{
"timeouts": timeouts.Attributes(ctx, TimeoutsOpts{/* ... */}),
},
/* ... */Additionally, create the following exported types for retrieving time.Duration for use in timeouts within CRUD functions:
func Create(ctx context.Context, obj types.Object) (*time.Duration, diag.Diagnostics)
func CreateDefault(ctx context.Context, obj types.Object, def time.Duration) time.Duration
func Read(ctx context.Context, obj types.Object) (*time.Duration, diag.Diagnostics)
func ReadDefault(ctx context.Context, obj types.Object, def time.Duration) time.Duration
func Update(ctx context.Context, obj types.Object) (*time.Duration, diag.Diagnostics)
func UpdateDefault(ctx context.Context, obj types.Object, def time.Duration) time.Duration
func Delete(ctx context.Context, obj types.Object) (*time.Duration, diag.Diagnostics)
func DeleteDefault(ctx context.Context, obj types.Object, def time.Duration) time.DurationAdditional Information
No response
Code of Conduct
- I agree to follow this project's Code of Conduct