Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

all: Add acceptance tests for write-only attributes #293

Draft
wants to merge 37 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
4ee9165
Add SDKv2 resource with write-only attribute and tests
SBGoods Nov 26, 2024
cc9487d
Merge branch 'main' into SBGoods/write-only-testing
austinvalle Dec 17, 2024
699359a
updated go mod
austinvalle Dec 17, 2024
ef84121
add some initial smoke tests for write-only framework
austinvalle Dec 17, 2024
4d3ff45
simplify w/o tests
austinvalle Dec 18, 2024
2f731d9
some SDKv2 happy path tests
austinvalle Dec 19, 2024
5fe0047
add double nested set
austinvalle Dec 19, 2024
c5a6557
enforce data consistency on sdkv2 tests
austinvalle Dec 19, 2024
0e9d2de
write only negative tests for SDKv2
austinvalle Dec 19, 2024
dd723bb
Merge branch 'main' into SBGoods/write-only-testing
austinvalle Jan 2, 2025
4229766
verify config on update
austinvalle Jan 2, 2025
8e9d941
add nested attribute with write-only attr
austinvalle Jan 2, 2025
b73b034
remove unused schema attribute
austinvalle Jan 2, 2025
e08f258
remove unused provider attribute
austinvalle Jan 2, 2025
b9c211d
diff
austinvalle Jan 2, 2025
ffa3961
refactor test to avoid paths
austinvalle Jan 2, 2025
200d66f
add negative tests for framework providers w/ old terraform versions
austinvalle Jan 2, 2025
a75e3da
testing version from pkg
austinvalle Jan 2, 2025
05cdb67
write-once resource
austinvalle Jan 3, 2025
6f7403d
more SDKv2 tests with validations
austinvalle Jan 3, 2025
1e5bb88
testing state nulling for fw providers
austinvalle Jan 6, 2025
922e213
add write-once tests to framework providers
austinvalle Jan 6, 2025
3269cfa
add write-only validation tests for FW providers
austinvalle Jan 6, 2025
0b7a3de
update copywrite
austinvalle Jan 6, 2025
b30fd01
add data check tests
austinvalle Jan 6, 2025
d33be2e
move resource state test
austinvalle Jan 7, 2025
26d1f0e
comment
austinvalle Jan 7, 2025
ef4cd5e
upgrade resource state bugged test
austinvalle Jan 7, 2025
4358d6b
comment
austinvalle Jan 7, 2025
69570b8
Merge branch 'main' into SBGoods/write-only-testing
austinvalle Jan 8, 2025
688c526
protocolv6 data checks
austinvalle Jan 8, 2025
0a2580b
requires_replace temp example
austinvalle Jan 9, 2025
04075d7
remove replace example and add import for sdkv2
austinvalle Jan 9, 2025
ac8f637
add TODO comment with readresource test
austinvalle Jan 9, 2025
58fc242
import and move state fw tests
austinvalle Jan 9, 2025
f2caa1f
upgrade resource tests
austinvalle Jan 9, 2025
5111b99
add upgrade test
austinvalle Jan 9, 2025
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
22 changes: 12 additions & 10 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@ module github.com/hashicorp/terraform-provider-corner
go 1.22.7

require (
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320
github.com/hashicorp/go-memdb v1.3.4
github.com/hashicorp/terraform-json v0.24.0
github.com/hashicorp/terraform-plugin-framework v1.13.0
github.com/hashicorp/terraform-plugin-framework v1.13.1-0.20250102211725-428efefe5acc
Copy link
Member Author

@austinvalle austinvalle Jan 10, 2025

Choose a reason for hiding this comment

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

TODO: Update with released version once available

github.com/hashicorp/terraform-plugin-framework-nettypes v0.2.0
github.com/hashicorp/terraform-plugin-framework-timeouts v0.4.1
github.com/hashicorp/terraform-plugin-framework-timetypes v0.5.0
github.com/hashicorp/terraform-plugin-go v0.25.0
github.com/hashicorp/terraform-plugin-mux v0.17.0
github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.0
github.com/hashicorp/terraform-plugin-testing v1.11.0
github.com/hashicorp/terraform-plugin-framework-validators v0.16.0
github.com/hashicorp/terraform-plugin-go v0.25.1-0.20241217173851-dcf8f64dbfaa
github.com/hashicorp/terraform-plugin-mux v0.17.1-0.20241217174601-fdf2e5e009de
github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.1-0.20250103201413-5f29273ad6f0
github.com/hashicorp/terraform-plugin-testing v1.11.1-0.20250102212914-99297ce85154
Comment on lines +14 to +17
Copy link
Member Author

Choose a reason for hiding this comment

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

TODO: Update with released versions once available

github.com/zclconf/go-cty v1.16.0
)

Expand All @@ -26,7 +29,6 @@ require (
github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-checkpoint v0.5.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 // indirect
github.com/hashicorp/go-hclog v1.6.3 // indirect
github.com/hashicorp/go-immutable-radix v1.3.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
Expand Down Expand Up @@ -56,13 +58,13 @@ require (
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
golang.org/x/crypto v0.31.0 // indirect
golang.org/x/mod v0.21.0 // indirect
golang.org/x/net v0.28.0 // indirect
golang.org/x/net v0.29.0 // indirect
golang.org/x/sync v0.10.0 // indirect
golang.org/x/sys v0.28.0 // indirect
golang.org/x/text v0.21.0 // indirect
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect
google.golang.org/grpc v1.67.1 // indirect
google.golang.org/protobuf v1.35.1 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
google.golang.org/grpc v1.68.1 // indirect
google.golang.org/protobuf v1.35.2 // indirect
)
40 changes: 22 additions & 18 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -81,22 +81,26 @@ github.com/hashicorp/terraform-exec v0.21.0 h1:uNkLAe95ey5Uux6KJdua6+cv8asgILFVW
github.com/hashicorp/terraform-exec v0.21.0/go.mod h1:1PPeMYou+KDUSSeRE9szMZ/oHf4fYUmB923Wzbq1ICg=
github.com/hashicorp/terraform-json v0.24.0 h1:rUiyF+x1kYawXeRth6fKFm/MdfBS6+lW4NbeATsYz8Q=
github.com/hashicorp/terraform-json v0.24.0/go.mod h1:Nfj5ubo9xbu9uiAoZVBsNOjvNKB66Oyrvtit74kC7ow=
github.com/hashicorp/terraform-plugin-framework v1.13.0 h1:8OTG4+oZUfKgnfTdPTJwZ532Bh2BobF4H+yBiYJ/scw=
github.com/hashicorp/terraform-plugin-framework v1.13.0/go.mod h1:j64rwMGpgM3NYXTKuxrCnyubQb/4VKldEKlcG8cvmjU=
github.com/hashicorp/terraform-plugin-framework v1.13.1-0.20250102211725-428efefe5acc h1:05/WFc86cMPmw85GuVdoPRpBq9iQ7YyR9pYIsRcI0zs=
github.com/hashicorp/terraform-plugin-framework v1.13.1-0.20250102211725-428efefe5acc/go.mod h1:qBKUqe1lv1NZcsO5pBjiKd5YuNDUeqvV1w8w5df/8WI=
github.com/hashicorp/terraform-plugin-framework-nettypes v0.2.0 h1:Zap24rkky7SvNGGNYHMKFhAriP6+6riI21BMYOYgLRE=
github.com/hashicorp/terraform-plugin-framework-nettypes v0.2.0/go.mod h1:CYPq+I5bWsmI8021VJY85hAyOeiEEQpdGW+NapdQn7A=
github.com/hashicorp/terraform-plugin-framework-timeouts v0.4.1 h1:gm5b1kHgFFhaKFhm4h2TgvMUlNzFAtUqlcOWnWPm+9E=
github.com/hashicorp/terraform-plugin-framework-timeouts v0.4.1/go.mod h1:MsjL1sQ9L7wGwzJ5RjcI6FzEMdyoBnw+XK8ZnOvQOLY=
github.com/hashicorp/terraform-plugin-framework-timetypes v0.5.0 h1:v3DapR8gsp3EM8fKMh6up9cJUFQ2iRaFsYLP8UJnCco=
github.com/hashicorp/terraform-plugin-framework-timetypes v0.5.0/go.mod h1:c3PnGE9pHBDfdEVG9t1S1C9ia5LW+gkFR0CygXlM8ak=
github.com/hashicorp/terraform-plugin-go v0.25.0 h1:oi13cx7xXA6QciMcpcFi/rwA974rdTxjqEhXJjbAyks=
github.com/hashicorp/terraform-plugin-go v0.25.0/go.mod h1:+SYagMYadJP86Kvn+TGeV+ofr/R3g4/If0O5sO96MVw=
github.com/hashicorp/terraform-plugin-framework-validators v0.16.0 h1:O9QqGoYDzQT7lwTXUsZEtgabeWW96zUBh47Smn2lkFA=
github.com/hashicorp/terraform-plugin-framework-validators v0.16.0/go.mod h1:Bh89/hNmqsEWug4/XWKYBwtnw3tbz5BAy1L1OgvbIaY=
github.com/hashicorp/terraform-plugin-go v0.25.1-0.20241217173851-dcf8f64dbfaa h1:GOXZVYZrfDrWxZMHdSNqZKDwayH8WBBtyOLx25ekwv8=
github.com/hashicorp/terraform-plugin-go v0.25.1-0.20241217173851-dcf8f64dbfaa/go.mod h1:OKJU8uauqiLVRWjlFB0KIgK++baq26qfvOU1IVycx9k=
github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0=
github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow=
github.com/hashicorp/terraform-plugin-mux v0.17.0 h1:/J3vv3Ps2ISkbLPiZOLspFcIZ0v5ycUXCEQScudGCCw=
github.com/hashicorp/terraform-plugin-mux v0.17.0/go.mod h1:yWuM9U1Jg8DryNfvCp+lH70WcYv6D8aooQxxxIzFDsE=
github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.0 h1:wyKCCtn6pBBL46c1uIIBNUOWlNfYXfXpVo16iDyLp8Y=
github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.0/go.mod h1:B0Al8NyYVr8Mp/KLwssKXG1RqnTk7FySqSn4fRuLNgw=
github.com/hashicorp/terraform-plugin-testing v1.11.0 h1:MeDT5W3YHbONJt2aPQyaBsgQeAIckwPX41EUHXEn29A=
github.com/hashicorp/terraform-plugin-testing v1.11.0/go.mod h1:WNAHQ3DcgV/0J+B15WTE6hDvxcUdkPPpnB1FR3M910U=
github.com/hashicorp/terraform-plugin-mux v0.17.1-0.20241217174601-fdf2e5e009de h1:qjSTbKECIWAEO5hBGqabykC/xwrAYIrD7fKSVKldFhY=
github.com/hashicorp/terraform-plugin-mux v0.17.1-0.20241217174601-fdf2e5e009de/go.mod h1:To/3Wdozxp5QLvgcR4lKOdfiBcG70eoFZepcXro+nPQ=
github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.1-0.20250103201413-5f29273ad6f0 h1:wBngDRqcqKObWtg/2e/FPcMaL9SLtkBePd5adYjCcMo=
github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.1-0.20250103201413-5f29273ad6f0/go.mod h1:wsPZ9W0E/8tID4aejTrYrNPlJS8YhkEepeMeZlUaB8M=
github.com/hashicorp/terraform-plugin-testing v1.11.1-0.20250102212914-99297ce85154 h1:uK2Y1p/2RqvCRxytmByMywbKNdTpxvarGDDoiA7Qkcg=
github.com/hashicorp/terraform-plugin-testing v1.11.1-0.20250102212914-99297ce85154/go.mod h1:/HZY+vE/VIsnSNEkvgdpIiuMp6gT+u6HwTf6vs5Cfkk=
github.com/hashicorp/terraform-registry-address v0.2.3 h1:2TAiKJ1A3MAkZlH1YI/aTVcLZRu7JseiXNRHbOAyoTI=
github.com/hashicorp/terraform-registry-address v0.2.3/go.mod h1:lFHA76T8jfQteVfT7caREqguFrW3c4MFSPhZB7HHgUM=
github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ=
Expand Down Expand Up @@ -172,8 +176,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand Down Expand Up @@ -212,14 +216,14 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E=
google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
google.golang.org/grpc v1.68.1 h1:oI5oTa11+ng8r8XMMN7jAOmWfPZWbYpCFaMUTACxkM0=
google.golang.org/grpc v1.68.1/go.mod h1:+q1XYFJjShcqn0QZHvCyeR4CXPA+llXIeUIfIe00waw=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io=
google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
76 changes: 76 additions & 0 deletions internal/cornertesting/prefer_write_only_attribute.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package cornertesting

import (
"context"
"fmt"

"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
)

func PreferWriteOnlyAttribute(oldAttribute, newAttribute path.Expression) resource.ConfigValidator {
return preferWriteOnlyAttributeValidator{
oldAttribute: oldAttribute,
newAttribute: newAttribute,
}
}

var _ resource.ConfigValidator = &preferWriteOnlyAttributeValidator{}

type preferWriteOnlyAttributeValidator struct {
oldAttribute path.Expression
newAttribute path.Expression
}

func (v preferWriteOnlyAttributeValidator) Description(ctx context.Context) string {
return v.MarkdownDescription(ctx)
}

func (v preferWriteOnlyAttributeValidator) MarkdownDescription(_ context.Context) string {
return fmt.Sprintf("If the client supports write-only attributes (Terraform v1.11+), attribute %s should be used in-place of %s", v.newAttribute, v.oldAttribute)
}

func (v preferWriteOnlyAttributeValidator) ValidateResource(ctx context.Context, req resource.ValidateConfigRequest, resp *resource.ValidateConfigResponse) {
// Write-only attributes are not supported in the client, so no warning should be raised.
if !req.ClientCapabilities.WriteOnlyAttributesAllowed {
return
}

matchedOldPaths, matchedOldPathsDiags := req.Config.PathMatches(ctx, v.oldAttribute)
resp.Diagnostics.Append(matchedOldPathsDiags...)
if resp.Diagnostics.HasError() {
return
}

var diags diag.Diagnostics
for _, matchedOldPath := range matchedOldPaths {
var value attr.Value
getAttributeDiags := req.Config.GetAttribute(ctx, matchedOldPath, &value)

diags.Append(getAttributeDiags...)

// Collect all errors
if getAttributeDiags.HasError() {
continue
}

// Value must not be null or unknown to trigger validation error
if value.IsNull() || value.IsUnknown() {
continue
}

diags.AddAttributeWarning(
matchedOldPath,
"Available Write-Only Attribute Alternative",
fmt.Sprintf("The attribute %s has a WriteOnly version %s available. "+
"Use the WriteOnly version of the attribute when possible.", matchedOldPath, v.newAttribute),
)
}

resp.Diagnostics = diags
}
41 changes: 41 additions & 0 deletions internal/cornertesting/string_required_on_create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package cornertesting

import (
"context"
"fmt"

"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
)

func RequiredOnCreate() planmodifier.String {
return requiredOnCreateModifier{}
}

type requiredOnCreateModifier struct{}

func (m requiredOnCreateModifier) Description(_ context.Context) string {
return "This attribute is required only when creating the resource."
}

func (m requiredOnCreateModifier) MarkdownDescription(_ context.Context) string {
return "This attribute is required only when creating the resource."
}

func (m requiredOnCreateModifier) PlanModifyString(ctx context.Context, req planmodifier.StringRequest, resp *planmodifier.StringResponse) {
// If there is a non-null state, we are destroying or updating so no validation is needed
if !req.State.Raw.IsNull() {
return
}

// We are creating, but the attribute value is not present in config, return an error.
if req.ConfigValue.IsNull() {
resp.Diagnostics.AddAttributeError(
req.Path,
"Attribute Required when Creating",
fmt.Sprintf("Must set a configuration value for the %s attribute when creating.", req.Path.String()),
)
return
}
}
18 changes: 17 additions & 1 deletion internal/framework5provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,16 @@ func NewWithEphemeralSpy(spy *EphemeralResourceSpyClient) provider.Provider {
}
}

func NewWithUpgradeVersion(version int64) provider.Provider {
return &testProvider{
ephSpyClient: &EphemeralResourceSpyClient{},
upgradeVersion: version,
}
}

type testProvider struct {
ephSpyClient *EphemeralResourceSpyClient
ephSpyClient *EphemeralResourceSpyClient
upgradeVersion int64
}

func (p *testProvider) Metadata(_ context.Context, _ provider.MetadataRequest, resp *provider.MetadataResponse) {
Expand Down Expand Up @@ -91,6 +99,14 @@ func (p *testProvider) Resources(_ context.Context) []func() resource.Resource {
NewTFSDKReflectionResource,
NewMoveStateResource,
NewSetNestedBlockWithDefaultsResource,
NewWriteOnlyResource,
NewWriteOnceResource,
NewWriteOnlyValidationsResource,
NewWriteOnlyImportResource,
NewWriteOnlyMoveResource,
func() resource.Resource {
return NewWriteOnlyUpgradeResource(p.upgradeVersion)
},
}
}

Expand Down
92 changes: 92 additions & 0 deletions internal/framework5provider/writeonce_resource.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package framework

import (
"context"

"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"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-provider-corner/internal/cornertesting"
)

var _ resource.Resource = WriteOnceResource{}

func NewWriteOnceResource() resource.Resource {
return &WriteOnceResource{}
}

type WriteOnceResource struct{}

func (r WriteOnceResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_writeonce"
}

func (r WriteOnceResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
"trigger_attr": schema.StringAttribute{
Required: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.RequiresReplace(),
},
},
// The only place that validation can reference prior state (which is required to determine if the planned action is
// a create, i.e, prior state is null) is during plan modification. So the plan modifier implementation is responsible
// for applying the "write-once" validation
"writeonce_string": schema.StringAttribute{
Optional: true,
WriteOnly: true,
PlanModifiers: []planmodifier.String{
cornertesting.RequiredOnCreate(),
},
},
},
}
}

func (r WriteOnceResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
var config WriteOnceResourceModel
resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
if resp.Diagnostics.HasError() {
return
}

resp.Diagnostics.Append(assertWriteOnlyVal(ctx, req.Config, path.Root("writeonce_string"), types.StringValue("fakepassword"))...)
if resp.Diagnostics.HasError() {
return
}

// Since all attributes are in configuration, we write it back directly to test that the write-only attributes
// are nulled out before sending back to TF Core.
resp.Diagnostics.Append(resp.State.Set(ctx, &config)...)
}

func (r WriteOnceResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
var data WriteOnceResourceModel

resp.Diagnostics.Append(req.State.Get(ctx, &data)...)

if resp.Diagnostics.HasError() {
return
}

resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}

func (r WriteOnceResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
// Once created, the only operation that can occur is replacement (delete/create)
}

func (r WriteOnceResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
}

type WriteOnceResourceModel struct {
TriggerAttr types.String `tfsdk:"trigger_attr"`
WriteOnlyString types.String `tfsdk:"writeonce_string"`
}
Loading
Loading