Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changes/unreleased/FEATURES-20260223-113850.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
kind: FEATURES
body: Adds functions and types for statestore timeouts.
time: 2026-02-23T11:38:50.757069-05:00
custom:
Issue: "222"
12 changes: 6 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@ go 1.24.0

require (
github.com/google/go-cmp v0.7.0
github.com/hashicorp/terraform-plugin-framework v1.17.0
github.com/hashicorp/terraform-plugin-go v0.29.0
github.com/hashicorp/terraform-plugin-framework v1.17.1-0.20260223163459-7b6eb103b2e8
github.com/hashicorp/terraform-plugin-go v0.29.1-0.20260122204301-b0a6aca80fd7
Comment on lines +7 to +8
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we need to wait for Framework and plugin-go to be released until we merge this PR (or at least until we release the timeouts package after merging this)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this PR just needs to be rebased and it'll bring in the right framework Go module 👍🏻

github.com/hashicorp/terraform-plugin-log v0.10.0
)

require (
github.com/fatih/color v1.15.0 // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/hashicorp/go-hclog v1.6.3 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
golang.org/x/sys v0.35.0 // indirect
golang.org/x/sys v0.38.0 // indirect
)
26 changes: 12 additions & 14 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,26 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
github.com/hashicorp/terraform-plugin-framework v1.17.0 h1:JdX50CFrYcYFY31gkmitAEAzLKoBgsK+iaJjDC8OexY=
github.com/hashicorp/terraform-plugin-framework v1.17.0/go.mod h1:4OUXKdHNosX+ys6rLgVlgklfxN3WHR5VHSOABeS/BM0=
github.com/hashicorp/terraform-plugin-go v0.29.0 h1:1nXKl/nSpaYIUBU1IG/EsDOX0vv+9JxAltQyDMpq5mU=
github.com/hashicorp/terraform-plugin-go v0.29.0/go.mod h1:vYZbIyvxyy0FWSmDHChCqKvI40cFTDGSb3D8D70i9GM=
github.com/hashicorp/terraform-plugin-framework v1.17.1-0.20260223163459-7b6eb103b2e8 h1:qRH/hDl3QCDJJyM3EkJkEyYvjXXJYGBiF2QH4C+1ZEk=
github.com/hashicorp/terraform-plugin-framework v1.17.1-0.20260223163459-7b6eb103b2e8/go.mod h1:mQc5Y3J0bqa7oJJienpRsn8c5RgxUeLgvNJhlHr3WAQ=
github.com/hashicorp/terraform-plugin-go v0.29.1-0.20260122204301-b0a6aca80fd7 h1:ViO8kjIwBFTqOrMT5GilsY8TKRjejAqSTyFjjdTMY1o=
github.com/hashicorp/terraform-plugin-go v0.29.1-0.20260122204301-b0a6aca80fd7/go.mod h1:q0rLI/Z8QaAhX+22MvIlGbFkHoOtwS58vaShJZPXndU=
github.com/hashicorp/terraform-plugin-log v0.10.0 h1:eu2kW6/QBVdN4P3Ju2WiB2W3ObjkAsyfBsL3Wh1fj3g=
github.com/hashicorp/terraform-plugin-log v0.10.0/go.mod h1:/9RR5Cv2aAbrqcTSdNmY1NRHP4E3ekrXRGjqORpXyB0=
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU=
github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
Expand All @@ -42,10 +41,9 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
83 changes: 83 additions & 0 deletions statestore/timeouts/schema.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Copyright IBM Corp. 2022, 2026
// SPDX-License-Identifier: MPL-2.0

package timeouts

import (
"context"

"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/statestore/schema"
"github.com/hashicorp/terraform-plugin-framework/types"

"github.com/hashicorp/terraform-plugin-framework-timeouts/internal/validators"
)

const (
attributeNameStateStore = "statestore"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See other comment, but this should be related to the operation the timeout applies to

)

// Opts is used as an argument to BlockWithOpts and AttributesWithOpts to indicate
// whether supplied descriptions should override default descriptions.
type Opts struct {
StateStoreDescription string
}

// AttributesWithOpts returns a schema.SingleNestedAttribute which contains an
// attribute for `Open`, which is defined as types.StringType and optional.
// A validator is used to verify that the value assigned to an attribute
// can be parsed as time.Duration. The supplied Opts are used to override defaults.
func AttributesWithOpts(ctx context.Context, opts Opts) schema.Attribute {
return schema.SingleNestedAttribute{
Attributes: attributesMap(opts),
CustomType: Type{
ObjectType: types.ObjectType{
AttrTypes: attrTypesMap(),
},
},
Optional: true,
}
}

// Attributes returns a schema.SingleNestedAttribute which contains an
// attribute for `Open`, which is defined as types.StringType and optional.
// A validator is used to verify that the value assigned to an attribute
// can be parsed as time.Duration.
func Attributes(ctx context.Context) schema.Attribute {
return schema.SingleNestedAttribute{
Attributes: attributesMap(Opts{}),
CustomType: Type{
ObjectType: types.ObjectType{
AttrTypes: attrTypesMap(),
},
},
Optional: true,
}
}

func attributesMap(opts Opts) map[string]schema.Attribute {
attribute := schema.StringAttribute{
Optional: true,
Description: `A string that can be [parsed as a duration](https://pkg.go.dev/time#ParseDuration) ` +
`consisting of numbers and unit suffixes, such as "30s" or "2h45m". Valid time units are ` +
`"s" (seconds), "m" (minutes), "h" (hours).`,
Validators: []validator.String{
validators.TimeDuration(),
},
}

if opts.StateStoreDescription != "" {
attribute.Description = opts.StateStoreDescription
}

return map[string]schema.Attribute{
attributeNameStateStore: attribute,
}
}

func attrTypesMap() map[string]attr.Type {
return map[string]attr.Type{
attributeNameStateStore: types.StringType,
}
}
134 changes: 134 additions & 0 deletions statestore/timeouts/schema_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
// Copyright IBM Corp. 2022, 2026
// SPDX-License-Identifier: MPL-2.0

package timeouts_test

import (
"context"
"testing"

"github.com/google/go-cmp/cmp"
"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/statestore/schema"
"github.com/hashicorp/terraform-plugin-framework/types"

"github.com/hashicorp/terraform-plugin-framework-timeouts/internal/validators"
"github.com/hashicorp/terraform-plugin-framework-timeouts/statestore/timeouts"
)

func TestAttributesWithOpts(t *testing.T) {
t.Parallel()

type testCase struct {
opts timeouts.Opts
expected schema.Attribute
}
tests := map[string]testCase{
"empty-opts": {
opts: timeouts.Opts{},
expected: schema.SingleNestedAttribute{
Attributes: map[string]schema.Attribute{
"statestore": schema.StringAttribute{
Optional: true,
Description: `A string that can be [parsed as a duration](https://pkg.go.dev/time#ParseDuration) ` +
`consisting of numbers and unit suffixes, such as "30s" or "2h45m". Valid time units are ` +
`"s" (seconds), "m" (minutes), "h" (hours).`,
Validators: []validator.String{
validators.TimeDuration(),
},
},
},
CustomType: timeouts.Type{
ObjectType: types.ObjectType{
AttrTypes: map[string]attr.Type{
"statestore": types.StringType,
},
},
},
Optional: true,
},
},
"statestore-opts-description": {
opts: timeouts.Opts{
StateStoreDescription: "statestore description",
},
expected: schema.SingleNestedAttribute{
Attributes: map[string]schema.Attribute{
"statestore": schema.StringAttribute{
Optional: true,
Description: "statestore description",
Validators: []validator.String{
validators.TimeDuration(),
},
},
},
CustomType: timeouts.Type{
ObjectType: types.ObjectType{
AttrTypes: map[string]attr.Type{
"statestore": types.StringType,
},
},
},
Optional: true,
},
},
}

for name, test := range tests {

t.Run(name, func(t *testing.T) {
t.Parallel()
actual := timeouts.AttributesWithOpts(context.Background(), test.opts)

if diff := cmp.Diff(actual, test.expected); diff != "" {
t.Errorf("unexpected block difference: %s", diff)
}
})
}
}

func TestAttributes(t *testing.T) {
t.Parallel()

type testCase struct {
expected schema.Attribute
}
tests := map[string]testCase{
"statestore": {
expected: schema.SingleNestedAttribute{
Attributes: map[string]schema.Attribute{
"statestore": schema.StringAttribute{
Optional: true,
Description: `A string that can be [parsed as a duration](https://pkg.go.dev/time#ParseDuration) ` +
`consisting of numbers and unit suffixes, such as "30s" or "2h45m". Valid time units are ` +
`"s" (seconds), "m" (minutes), "h" (hours).`,
Validators: []validator.String{
validators.TimeDuration(),
},
},
},
CustomType: timeouts.Type{
ObjectType: types.ObjectType{
AttrTypes: map[string]attr.Type{
"statestore": types.StringType,
},
},
},
Optional: true,
},
},
}

for name, test := range tests {

t.Run(name, func(t *testing.T) {
t.Parallel()
actual := timeouts.Attributes(context.Background())

if diff := cmp.Diff(actual, test.expected); diff != "" {
t.Errorf("unexpected block difference: %s", diff)
}
})
}
}
Loading