Skip to content

Commit e0355d6

Browse files
authored
Add support for write-only attributes in actions (#1233)
* Add support for write-only attributes in action schema * Add changelog entry * Update comments to clarify usage
1 parent 8855023 commit e0355d6

31 files changed

+286
-37
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
kind: FEATURES
2+
body: 'action/schema: Added `WriteOnly` schema field for action schemas.'
3+
time: 2025-10-14T17:37:39.087475-04:00
4+
custom:
5+
Issue: "1233"

action/schema/bool_attribute.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@ type BoolAttribute struct {
104104
// xattr.TypeWithValidate interface, the validators defined in this field
105105
// are run in addition to the validation defined by the type.
106106
Validators []validator.Bool
107+
108+
// WriteOnly indicates whether this attribute can accept ephemeral values
109+
// or not. If WriteOnly is true, either Optional or Required must also be true.
110+
WriteOnly bool
107111
}
108112

109113
// ApplyTerraform5AttributePathStep always returns an error as it is not
@@ -166,9 +170,9 @@ func (a BoolAttribute) IsSensitive() bool {
166170
return false
167171
}
168172

169-
// IsWriteOnly always returns false as action schema attributes cannot be WriteOnly.
173+
// IsWriteOnly returns the WriteOnly field value.
170174
func (a BoolAttribute) IsWriteOnly() bool {
171-
return false
175+
return a.WriteOnly
172176
}
173177

174178
// IsRequiredForImport returns false as this behavior is only relevant

action/schema/bool_attribute_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,12 @@ func TestBoolAttributeIsWriteOnly(t *testing.T) {
370370
attribute: schema.BoolAttribute{},
371371
expected: false,
372372
},
373+
"writeOnly": {
374+
attribute: schema.BoolAttribute{
375+
WriteOnly: true,
376+
},
377+
expected: true,
378+
},
373379
}
374380

375381
for name, testCase := range testCases {

action/schema/dynamic_attribute.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,10 @@ type DynamicAttribute struct {
105105
// xattr.TypeWithValidate interface, the validators defined in this field
106106
// are run in addition to the validation defined by the type.
107107
Validators []validator.Dynamic
108+
109+
// WriteOnly indicates whether this attribute can accept ephemeral values
110+
// or not. If WriteOnly is true, either Optional or Required must also be true.
111+
WriteOnly bool
108112
}
109113

110114
// ApplyTerraform5AttributePathStep always returns an error as it is not
@@ -167,9 +171,9 @@ func (a DynamicAttribute) IsSensitive() bool {
167171
return false
168172
}
169173

170-
// IsWriteOnly always returns false as action schema attributes cannot be WriteOnly.
174+
// IsWriteOnly returns the WriteOnly field value.
171175
func (a DynamicAttribute) IsWriteOnly() bool {
172-
return false
176+
return a.WriteOnly
173177
}
174178

175179
// IsRequiredForImport returns false as this behavior is only relevant

action/schema/dynamic_attribute_test.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,15 @@ import (
99
"testing"
1010

1111
"github.com/google/go-cmp/cmp"
12+
"github.com/hashicorp/terraform-plugin-go/tftypes"
13+
1214
"github.com/hashicorp/terraform-plugin-framework/action/schema"
1315
"github.com/hashicorp/terraform-plugin-framework/attr"
1416
"github.com/hashicorp/terraform-plugin-framework/internal/fwschema"
1517
"github.com/hashicorp/terraform-plugin-framework/internal/testing/testschema"
1618
"github.com/hashicorp/terraform-plugin-framework/internal/testing/testtypes"
1719
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
1820
"github.com/hashicorp/terraform-plugin-framework/types"
19-
"github.com/hashicorp/terraform-plugin-go/tftypes"
2021
)
2122

2223
func TestDynamicAttributeApplyTerraform5AttributePathStep(t *testing.T) {
@@ -369,6 +370,12 @@ func TestDynamicAttributeIsWriteOnly(t *testing.T) {
369370
attribute: schema.DynamicAttribute{},
370371
expected: false,
371372
},
373+
"writeOnly": {
374+
attribute: schema.DynamicAttribute{
375+
WriteOnly: true,
376+
},
377+
expected: true,
378+
},
372379
}
373380

374381
for name, testCase := range testCases {

action/schema/float32_attribute.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ type Float32Attribute struct {
107107
// xattr.TypeWithValidate interface, the validators defined in this field
108108
// are run in addition to the validation defined by the type.
109109
Validators []validator.Float32
110+
111+
// WriteOnly indicates whether this attribute can accept ephemeral values
112+
// or not. If WriteOnly is true, either Optional or Required must also be true.
113+
WriteOnly bool
110114
}
111115

112116
// ApplyTerraform5AttributePathStep always returns an error as it is not
@@ -169,9 +173,9 @@ func (a Float32Attribute) IsSensitive() bool {
169173
return false
170174
}
171175

172-
// IsWriteOnly always returns false as action schema attributes cannot be WriteOnly.
176+
// IsWriteOnly returns the WriteOnly field value.
173177
func (a Float32Attribute) IsWriteOnly() bool {
174-
return false
178+
return a.WriteOnly
175179
}
176180

177181
// IsRequiredForImport returns false as this behavior is only relevant

action/schema/float32_attribute_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,12 @@ func TestFloat32AttributeIsWriteOnly(t *testing.T) {
370370
attribute: schema.Float32Attribute{},
371371
expected: false,
372372
},
373+
"writeOnly": {
374+
attribute: schema.Float32Attribute{
375+
WriteOnly: true,
376+
},
377+
expected: true,
378+
},
373379
}
374380

375381
for name, testCase := range testCases {

action/schema/float64_attribute.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ type Float64Attribute struct {
107107
// xattr.TypeWithValidate interface, the validators defined in this field
108108
// are run in addition to the validation defined by the type.
109109
Validators []validator.Float64
110+
111+
// WriteOnly indicates whether this attribute can accept ephemeral values
112+
// or not. If WriteOnly is true, either Optional or Required must also be true.
113+
WriteOnly bool
110114
}
111115

112116
// ApplyTerraform5AttributePathStep always returns an error as it is not
@@ -169,9 +173,9 @@ func (a Float64Attribute) IsSensitive() bool {
169173
return false
170174
}
171175

172-
// IsWriteOnly always returns false as action schema attributes cannot be WriteOnly.
176+
// IsWriteOnly returns the WriteOnly field value.
173177
func (a Float64Attribute) IsWriteOnly() bool {
174-
return false
178+
return a.WriteOnly
175179
}
176180

177181
// IsRequiredForImport returns false as this behavior is only relevant

action/schema/float64_attribute_test.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ func TestFloat64AttributeIsSensitive(t *testing.T) {
359359
}
360360
}
361361

362-
func TestFloat54AttributeIsWriteOnly(t *testing.T) {
362+
func TestFloat64AttributeIsWriteOnly(t *testing.T) {
363363
t.Parallel()
364364

365365
testCases := map[string]struct {
@@ -370,6 +370,12 @@ func TestFloat54AttributeIsWriteOnly(t *testing.T) {
370370
attribute: schema.Float64Attribute{},
371371
expected: false,
372372
},
373+
"writeOnly": {
374+
attribute: schema.Float64Attribute{
375+
WriteOnly: true,
376+
},
377+
expected: true,
378+
},
373379
}
374380

375381
for name, testCase := range testCases {

action/schema/int32_attribute.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ type Int32Attribute struct {
107107
// xattr.TypeWithValidate interface, the validators defined in this field
108108
// are run in addition to the validation defined by the type.
109109
Validators []validator.Int32
110+
111+
// WriteOnly indicates whether this attribute can accept ephemeral values
112+
// or not. If WriteOnly is true, either Optional or Required must also be true.
113+
WriteOnly bool
110114
}
111115

112116
// ApplyTerraform5AttributePathStep always returns an error as it is not
@@ -169,9 +173,9 @@ func (a Int32Attribute) IsSensitive() bool {
169173
return false
170174
}
171175

172-
// IsWriteOnly always returns false as action schema attributes cannot be WriteOnly.
176+
// IsWriteOnly returns the WriteOnly field value.
173177
func (a Int32Attribute) IsWriteOnly() bool {
174-
return false
178+
return a.WriteOnly
175179
}
176180

177181
// IsRequiredForImport returns false as this behavior is only relevant

0 commit comments

Comments
 (0)