Skip to content

Commit 90acf3b

Browse files
authored
Adjust Required and Default attributes to ComputedOptional (#42)
Reference: #38 This implements the typical provider development behavior of allowing a default value on an API required value to make its configuration optional. It is unclear if provider developers will need to adjust this behavior, but that can be sorted out in the future. Any API-intended behaviors that must be preserved will be surfaced via additional properties in the code generation specification to prevent conflating them with Terraform-intended behaviors.
1 parent afe1725 commit 90acf3b

File tree

10 files changed

+84
-6
lines changed

10 files changed

+84
-6
lines changed

DESIGN.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ For the provider, all fields in the provided JSON schema (`provider.schema_ref`)
150150
If not required, then the field will be mapped as [Optional](https://developer.hashicorp.com/terraform/plugin/framework/handling-data/schemas#optional).
151151

152152
#### Resources
153-
For resources, all fields, in the `Create` operation `requestBody` OAS schema, marked as [required](https://json-schema.org/understanding-json-schema/reference/object.html#required-properties) will be mapped as a [Required](https://developer.hashicorp.com/terraform/plugin/framework/handling-data/schemas#required) attribute.
153+
For resources, all fields, in the `Create` operation `requestBody` OAS schema, marked as [required](https://json-schema.org/understanding-json-schema/reference/object.html#required-properties) will be mapped as a [Required](https://developer.hashicorp.com/terraform/plugin/framework/handling-data/schemas#required) attribute. If [default](https://json-schema.org/draft/2020-12/json-schema-validation.html#name-default) is also specified, it will be mapped as [Computed](https://developer.hashicorp.com/terraform/plugin/framework/handling-data/schemas#computed) and [Optional](https://developer.hashicorp.com/terraform/plugin/framework/handling-data/schemas#optional) instead.
154154

155155
If not required, or if the field is in a different schema than the `Create` operation `requestbody`, then the field will be mapped as [Computed](https://developer.hashicorp.com/terraform/plugin/framework/handling-data/schemas#computed) and [Optional](https://developer.hashicorp.com/terraform/plugin/framework/handling-data/schemas#optional).
156156

internal/cmd/testdata/scaleway/generated_framework_ir.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2456,7 +2456,7 @@
24562456
{
24572457
"name": "arch",
24582458
"string": {
2459-
"computed_optional_required": "required",
2459+
"computed_optional_required": "computed_optional",
24602460
"default": {
24612461
"static": "x86_64"
24622462
},

internal/mapper/oas/bool.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ func (s *OASSchema) BuildBoolResource(name string, computability schema.Computed
2424
staticDefault, ok := s.Schema.Default.(bool)
2525

2626
if ok {
27+
if computability == schema.Required {
28+
result.Bool.ComputedOptionalRequired = schema.ComputedOptional
29+
}
30+
2731
result.Bool.Default = &schema.BoolDefault{
2832
Static: &staticDefault,
2933
}

internal/mapper/oas/bool_test.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ func TestBuildBoolResource(t *testing.T) {
5757
},
5858
"boolean attributes default": {
5959
schema: &base.Schema{
60-
Type: []string{"object"},
60+
Type: []string{"object"},
61+
Required: []string{"bool_prop_required_default_true"},
6162
Properties: map[string]*base.SchemaProxy{
6263
"bool_prop_default_false": base.CreateSchemaProxy(&base.Schema{
6364
Type: []string{"boolean"},
@@ -67,6 +68,10 @@ func TestBuildBoolResource(t *testing.T) {
6768
Type: []string{"boolean"},
6869
Default: true,
6970
}),
71+
"bool_prop_required_default_true": base.CreateSchemaProxy(&base.Schema{
72+
Type: []string{"boolean"},
73+
Default: true,
74+
}),
7075
},
7176
},
7277
expectedAttributes: &[]resource.Attribute{
@@ -88,6 +93,16 @@ func TestBuildBoolResource(t *testing.T) {
8893
},
8994
},
9095
},
96+
{
97+
Name: "bool_prop_required_default_true",
98+
Bool: &resource.BoolAttribute{
99+
// Intentionally not required due to default
100+
ComputedOptionalRequired: schema.ComputedOptional,
101+
Default: &schema.BoolDefault{
102+
Static: pointer(true),
103+
},
104+
},
105+
},
91106
},
92107
},
93108
"boolean attributes deprecated": {

internal/mapper/oas/integer.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ func (s *OASSchema) BuildIntegerResource(name string, computability schema.Compu
2525
staticDefault, ok := s.Schema.Default.(int64)
2626

2727
if ok {
28+
if computability == schema.Required {
29+
result.Int64.ComputedOptionalRequired = schema.ComputedOptional
30+
}
31+
2832
result.Int64.Default = &schema.Int64Default{
2933
Static: &staticDefault,
3034
}

internal/mapper/oas/integer_test.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ func TestBuildIntegerResource(t *testing.T) {
5858
},
5959
"int64 attributes default": {
6060
schema: &base.Schema{
61-
Type: []string{"object"},
61+
Type: []string{"object"},
62+
Required: []string{"int64_prop_required_default_non_zero"},
6263
Properties: map[string]*base.SchemaProxy{
6364
"int64_prop_default_non_zero": base.CreateSchemaProxy(&base.Schema{
6465
Type: []string{"integer"},
@@ -68,6 +69,10 @@ func TestBuildIntegerResource(t *testing.T) {
6869
Type: []string{"integer"},
6970
Default: int64(0),
7071
}),
72+
"int64_prop_required_default_non_zero": base.CreateSchemaProxy(&base.Schema{
73+
Type: []string{"integer"},
74+
Default: int64(123),
75+
}),
7176
},
7277
},
7378
expectedAttributes: &[]resource.Attribute{
@@ -89,6 +94,16 @@ func TestBuildIntegerResource(t *testing.T) {
8994
},
9095
},
9196
},
97+
{
98+
Name: "int64_prop_required_default_non_zero",
99+
Int64: &resource.Int64Attribute{
100+
// Intentionally not required due to default
101+
ComputedOptionalRequired: schema.ComputedOptional,
102+
Default: &schema.Int64Default{
103+
Static: pointer(int64(123)),
104+
},
105+
},
106+
},
92107
},
93108
},
94109
"int64 attributes deprecated": {

internal/mapper/oas/number.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ func (s *OASSchema) BuildNumberResource(name string, computability schema.Comput
2828
staticDefault, ok := s.Schema.Default.(float64)
2929

3030
if ok {
31+
if computability == schema.Required {
32+
result.Float64.ComputedOptionalRequired = schema.ComputedOptional
33+
}
34+
3135
result.Float64.Default = &schema.Float64Default{
3236
Static: &staticDefault,
3337
}

internal/mapper/oas/number_test.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ func TestBuildNumberResource(t *testing.T) {
8484
},
8585
"float64 attributes default": {
8686
schema: &base.Schema{
87-
Type: []string{"object"},
87+
Type: []string{"object"},
88+
Required: []string{"float64_prop_required_default_non_zero"},
8889
Properties: map[string]*base.SchemaProxy{
8990
"float64_prop_default_non_zero": base.CreateSchemaProxy(&base.Schema{
9091
Type: []string{"number"},
@@ -96,6 +97,11 @@ func TestBuildNumberResource(t *testing.T) {
9697
Format: "double",
9798
Default: float64(0.0),
9899
}),
100+
"float64_prop_required_default_non_zero": base.CreateSchemaProxy(&base.Schema{
101+
Type: []string{"number"},
102+
Format: "double",
103+
Default: float64(123.45),
104+
}),
99105
},
100106
},
101107
expectedAttributes: &[]resource.Attribute{
@@ -117,6 +123,16 @@ func TestBuildNumberResource(t *testing.T) {
117123
},
118124
},
119125
},
126+
{
127+
Name: "float64_prop_required_default_non_zero",
128+
Float64: &resource.Float64Attribute{
129+
// Intentionally not required due to default
130+
ComputedOptionalRequired: schema.ComputedOptional,
131+
Default: &schema.Float64Default{
132+
Static: pointer(float64(123.45)),
133+
},
134+
},
135+
},
120136
},
121137
},
122138
"float64 attributes deprecated": {

internal/mapper/oas/string.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ func (s *OASSchema) BuildStringResource(name string, computability schema.Comput
2626
staticDefault, ok := s.Schema.Default.(string)
2727

2828
if ok {
29+
if computability == schema.Required {
30+
result.String.ComputedOptionalRequired = schema.ComputedOptional
31+
}
32+
2933
result.String.Default = &schema.StringDefault{
3034
Static: &staticDefault,
3135
}

internal/mapper/oas/string_test.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ func TestBuildStringResource(t *testing.T) {
6060
},
6161
"string attributes default": {
6262
schema: &base.Schema{
63-
Type: []string{"object"},
63+
Type: []string{"object"},
64+
Required: []string{"string_prop_required_default_non_empty"},
6465
Properties: map[string]*base.SchemaProxy{
6566
"string_prop_default_empty": base.CreateSchemaProxy(&base.Schema{
6667
Type: []string{"string"},
@@ -72,6 +73,11 @@ func TestBuildStringResource(t *testing.T) {
7273
Format: "double",
7374
Default: "test value",
7475
}),
76+
"string_prop_required_default_non_empty": base.CreateSchemaProxy(&base.Schema{
77+
Type: []string{"string"},
78+
Format: "double",
79+
Default: "test value",
80+
}),
7581
},
7682
},
7783
expectedAttributes: &[]resource.Attribute{
@@ -93,6 +99,16 @@ func TestBuildStringResource(t *testing.T) {
9399
},
94100
},
95101
},
102+
{
103+
Name: "string_prop_required_default_non_empty",
104+
String: &resource.StringAttribute{
105+
// Intentionally not required due to default
106+
ComputedOptionalRequired: schema.ComputedOptional,
107+
Default: &schema.StringDefault{
108+
Static: pointer("test value"),
109+
},
110+
},
111+
},
96112
},
97113
},
98114
"string attributes deprecated": {

0 commit comments

Comments
 (0)