Skip to content

Commit f1d72c3

Browse files
committed
Allow nested aliases
1 parent 91bb667 commit f1d72c3

File tree

8 files changed

+182
-8
lines changed

8 files changed

+182
-8
lines changed

internal/mapper/attrmapper/data_source_attributes.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99

1010
"github.com/hashicorp/terraform-plugin-codegen-openapi/internal/explorer"
1111
"github.com/hashicorp/terraform-plugin-codegen-spec/datasource"
12+
"github.com/hashicorp/terraform-plugin-codegen-spec/schema"
1213
)
1314

1415
type DataSourceAttribute interface {
@@ -20,6 +21,7 @@ type DataSourceAttribute interface {
2021

2122
type DataSourceNestedAttribute interface {
2223
ApplyNestedOverride([]string, explorer.Override) (DataSourceAttribute, error)
24+
NestedMerge([]string, DataSourceAttribute, schema.ComputedOptionalRequired) (DataSourceAttribute, error)
2325
}
2426

2527
type DataSourceAttributes []DataSourceAttribute
@@ -58,6 +60,46 @@ func (targetSlice DataSourceAttributes) Merge(mergeSlices ...DataSourceAttribute
5860
return targetSlice, errResult
5961
}
6062

63+
func (targetSlice DataSourceAttributes) MergeAttribute(path []string, attribute DataSourceAttribute, intermediateComputability schema.ComputedOptionalRequired) (DataSourceAttributes, error) {
64+
var errResult error
65+
if len(path) == 0 {
66+
return targetSlice, errResult
67+
}
68+
for i, target := range targetSlice {
69+
if target.GetName() == path[0] {
70+
71+
if len(path) > 1 {
72+
nestedTarget, ok := target.(DataSourceNestedAttribute)
73+
if !ok {
74+
// TODO: error? there is a nested override for an attribute that is not a nested type
75+
break
76+
}
77+
78+
// The attribute we need to override is deeper nested, move up
79+
nextPath := path[1:]
80+
81+
overriddenTarget, err := nestedTarget.NestedMerge(nextPath, attribute, intermediateComputability)
82+
errResult = errors.Join(errResult, err)
83+
84+
targetSlice[i] = overriddenTarget
85+
86+
} else {
87+
// No more path to traverse, apply merge, bidirectional
88+
overriddenTarget, err := attribute.Merge(target)
89+
errResult = errors.Join(errResult, err)
90+
overriddenTarget, err = overriddenTarget.Merge(attribute)
91+
errResult = errors.Join(errResult, err)
92+
93+
targetSlice[i] = overriddenTarget
94+
}
95+
96+
break
97+
}
98+
}
99+
100+
return targetSlice, errResult
101+
}
102+
61103
func (attributes DataSourceAttributes) ToSpec() []datasource.Attribute {
62104
specAttributes := make([]datasource.Attribute, 0, len(attributes))
63105
for _, attribute := range attributes {

internal/mapper/attrmapper/list_nested.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"github.com/hashicorp/terraform-plugin-codegen-spec/datasource"
1010
"github.com/hashicorp/terraform-plugin-codegen-spec/provider"
1111
"github.com/hashicorp/terraform-plugin-codegen-spec/resource"
12+
"github.com/hashicorp/terraform-plugin-codegen-spec/schema"
1213
)
1314

1415
type ResourceListNestedAttribute struct {
@@ -50,6 +51,16 @@ func (a *ResourceListNestedAttribute) ApplyNestedOverride(path []string, overrid
5051
return a, err
5152
}
5253

54+
func (a *ResourceListNestedAttribute) NestedMerge(path []string, attribute ResourceAttribute, intermediateComputability schema.ComputedOptionalRequired) (ResourceAttribute, error) {
55+
var err error
56+
a.NestedObject.Attributes, err = a.NestedObject.Attributes.MergeAttribute(path, attribute, intermediateComputability)
57+
if err == nil {
58+
a.ComputedOptionalRequired = intermediateComputability
59+
}
60+
61+
return a, err
62+
}
63+
5364
func (a *ResourceListNestedAttribute) ToSpec() resource.Attribute {
5465
a.ListNestedAttribute.NestedObject = resource.NestedAttributeObject{
5566
Attributes: a.NestedObject.Attributes.ToSpec(),
@@ -100,6 +111,16 @@ func (a *DataSourceListNestedAttribute) ApplyNestedOverride(path []string, overr
100111
return a, err
101112
}
102113

114+
func (a *DataSourceListNestedAttribute) NestedMerge(path []string, attribute DataSourceAttribute, intermediateComputability schema.ComputedOptionalRequired) (DataSourceAttribute, error) {
115+
var err error
116+
a.NestedObject.Attributes, err = a.NestedObject.Attributes.MergeAttribute(path, attribute, intermediateComputability)
117+
if err == nil {
118+
a.ComputedOptionalRequired = intermediateComputability
119+
}
120+
121+
return a, err
122+
}
123+
103124
func (a *DataSourceListNestedAttribute) ToSpec() datasource.Attribute {
104125
a.ListNestedAttribute.NestedObject = datasource.NestedAttributeObject{
105126
Attributes: a.NestedObject.Attributes.ToSpec(),

internal/mapper/attrmapper/map_nested.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"github.com/hashicorp/terraform-plugin-codegen-spec/datasource"
1010
"github.com/hashicorp/terraform-plugin-codegen-spec/provider"
1111
"github.com/hashicorp/terraform-plugin-codegen-spec/resource"
12+
"github.com/hashicorp/terraform-plugin-codegen-spec/schema"
1213
)
1314

1415
type ResourceMapNestedAttribute struct {
@@ -50,6 +51,16 @@ func (a *ResourceMapNestedAttribute) ApplyNestedOverride(path []string, override
5051
return a, err
5152
}
5253

54+
func (a *ResourceMapNestedAttribute) NestedMerge(path []string, attribute ResourceAttribute, intermediateComputability schema.ComputedOptionalRequired) (ResourceAttribute, error) {
55+
var err error
56+
a.NestedObject.Attributes, err = a.NestedObject.Attributes.MergeAttribute(path, attribute, intermediateComputability)
57+
if err == nil {
58+
a.ComputedOptionalRequired = intermediateComputability
59+
}
60+
61+
return a, err
62+
}
63+
5364
func (a *ResourceMapNestedAttribute) ToSpec() resource.Attribute {
5465
a.MapNestedAttribute.NestedObject = resource.NestedAttributeObject{
5566
Attributes: a.NestedObject.Attributes.ToSpec(),
@@ -100,6 +111,16 @@ func (a *DataSourceMapNestedAttribute) ApplyNestedOverride(path []string, overri
100111
return a, err
101112
}
102113

114+
func (a *DataSourceMapNestedAttribute) NestedMerge(path []string, attribute DataSourceAttribute, intermediateComputability schema.ComputedOptionalRequired) (DataSourceAttribute, error) {
115+
var err error
116+
a.NestedObject.Attributes, err = a.NestedObject.Attributes.MergeAttribute(path, attribute, intermediateComputability)
117+
if err == nil {
118+
a.ComputedOptionalRequired = intermediateComputability
119+
}
120+
121+
return a, err
122+
}
123+
103124
func (a *DataSourceMapNestedAttribute) ToSpec() datasource.Attribute {
104125
a.MapNestedAttribute.NestedObject = datasource.NestedAttributeObject{
105126
Attributes: a.NestedObject.Attributes.ToSpec(),

internal/mapper/attrmapper/resource_attributes.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99

1010
"github.com/hashicorp/terraform-plugin-codegen-openapi/internal/explorer"
1111
"github.com/hashicorp/terraform-plugin-codegen-spec/resource"
12+
"github.com/hashicorp/terraform-plugin-codegen-spec/schema"
1213
)
1314

1415
type ResourceAttribute interface {
@@ -20,6 +21,7 @@ type ResourceAttribute interface {
2021

2122
type ResourceNestedAttribute interface {
2223
ApplyNestedOverride([]string, explorer.Override) (ResourceAttribute, error)
24+
NestedMerge([]string, ResourceAttribute, schema.ComputedOptionalRequired) (ResourceAttribute, error)
2325
}
2426

2527
type ResourceAttributes []ResourceAttribute
@@ -58,6 +60,46 @@ func (targetSlice ResourceAttributes) Merge(mergeSlices ...ResourceAttributes) (
5860
return targetSlice, errResult
5961
}
6062

63+
func (targetSlice ResourceAttributes) MergeAttribute(path []string, attribute ResourceAttribute, intermediateComputability schema.ComputedOptionalRequired) (ResourceAttributes, error) {
64+
var errResult error
65+
if len(path) == 0 {
66+
return targetSlice, errResult
67+
}
68+
for i, target := range targetSlice {
69+
if target.GetName() == path[0] {
70+
71+
if len(path) > 1 {
72+
nestedTarget, ok := target.(ResourceNestedAttribute)
73+
if !ok {
74+
// TODO: error? there is a nested override for an attribute that is not a nested type
75+
break
76+
}
77+
78+
// The attribute we need to override is deeper nested, move up
79+
nextPath := path[1:]
80+
81+
overriddenTarget, err := nestedTarget.NestedMerge(nextPath, attribute, intermediateComputability)
82+
errResult = errors.Join(errResult, err)
83+
84+
targetSlice[i] = overriddenTarget
85+
86+
} else {
87+
// No more path to traverse, apply merge, bidirectional
88+
overriddenTarget, err := attribute.Merge(target)
89+
errResult = errors.Join(errResult, err)
90+
overriddenTarget, err = overriddenTarget.Merge(attribute)
91+
errResult = errors.Join(errResult, err)
92+
93+
targetSlice[i] = overriddenTarget
94+
}
95+
96+
break
97+
}
98+
}
99+
100+
return targetSlice, errResult
101+
}
102+
61103
func (attributes ResourceAttributes) ToSpec() []resource.Attribute {
62104
specAttributes := make([]resource.Attribute, 0, len(attributes))
63105
for _, attribute := range attributes {

internal/mapper/attrmapper/set_nested.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"github.com/hashicorp/terraform-plugin-codegen-spec/datasource"
1010
"github.com/hashicorp/terraform-plugin-codegen-spec/provider"
1111
"github.com/hashicorp/terraform-plugin-codegen-spec/resource"
12+
"github.com/hashicorp/terraform-plugin-codegen-spec/schema"
1213
)
1314

1415
type ResourceSetNestedAttribute struct {
@@ -50,6 +51,16 @@ func (a *ResourceSetNestedAttribute) ApplyNestedOverride(path []string, override
5051
return a, err
5152
}
5253

54+
func (a *ResourceSetNestedAttribute) NestedMerge(path []string, attribute ResourceAttribute, intermediateComputability schema.ComputedOptionalRequired) (ResourceAttribute, error) {
55+
var err error
56+
a.NestedObject.Attributes, err = a.NestedObject.Attributes.MergeAttribute(path, attribute, intermediateComputability)
57+
if err == nil {
58+
a.ComputedOptionalRequired = intermediateComputability
59+
}
60+
61+
return a, err
62+
}
63+
5364
func (a *ResourceSetNestedAttribute) ToSpec() resource.Attribute {
5465
a.SetNestedAttribute.NestedObject = resource.NestedAttributeObject{
5566
Attributes: a.NestedObject.Attributes.ToSpec(),
@@ -100,6 +111,16 @@ func (a *DataSourceSetNestedAttribute) ApplyNestedOverride(path []string, overri
100111
return a, err
101112
}
102113

114+
func (a *DataSourceSetNestedAttribute) NestedMerge(path []string, attribute DataSourceAttribute, intermediateComputability schema.ComputedOptionalRequired) (DataSourceAttribute, error) {
115+
var err error
116+
a.NestedObject.Attributes, err = a.NestedObject.Attributes.MergeAttribute(path, attribute, intermediateComputability)
117+
if err == nil {
118+
a.ComputedOptionalRequired = intermediateComputability
119+
}
120+
121+
return a, err
122+
}
123+
103124
func (a *DataSourceSetNestedAttribute) ToSpec() datasource.Attribute {
104125
a.SetNestedAttribute.NestedObject = datasource.NestedAttributeObject{
105126
Attributes: a.NestedObject.Attributes.ToSpec(),

internal/mapper/attrmapper/single_nested.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"github.com/hashicorp/terraform-plugin-codegen-spec/datasource"
1010
"github.com/hashicorp/terraform-plugin-codegen-spec/provider"
1111
"github.com/hashicorp/terraform-plugin-codegen-spec/resource"
12+
"github.com/hashicorp/terraform-plugin-codegen-spec/schema"
1213
)
1314

1415
type ResourceSingleNestedAttribute struct {
@@ -50,6 +51,16 @@ func (a *ResourceSingleNestedAttribute) ApplyNestedOverride(path []string, overr
5051
return a, err
5152
}
5253

54+
func (a *ResourceSingleNestedAttribute) NestedMerge(path []string, attribute ResourceAttribute, intermediateComputability schema.ComputedOptionalRequired) (ResourceAttribute, error) {
55+
var err error
56+
a.Attributes, err = a.Attributes.MergeAttribute(path, attribute, intermediateComputability)
57+
if err == nil {
58+
a.ComputedOptionalRequired = intermediateComputability
59+
}
60+
61+
return a, err
62+
}
63+
5364
func (a *ResourceSingleNestedAttribute) ToSpec() resource.Attribute {
5465
a.SingleNestedAttribute.Attributes = a.Attributes.ToSpec()
5566

@@ -98,6 +109,16 @@ func (a *DataSourceSingleNestedAttribute) ApplyNestedOverride(path []string, ove
98109
return a, err
99110
}
100111

112+
func (a *DataSourceSingleNestedAttribute) NestedMerge(path []string, attribute DataSourceAttribute, intermediateComputability schema.ComputedOptionalRequired) (DataSourceAttribute, error) {
113+
var err error
114+
a.Attributes, err = a.Attributes.MergeAttribute(path, attribute, intermediateComputability)
115+
if err == nil {
116+
a.ComputedOptionalRequired = intermediateComputability
117+
}
118+
119+
return a, err
120+
}
121+
101122
func (a *DataSourceSingleNestedAttribute) ToSpec() datasource.Attribute {
102123
a.SingleNestedAttribute.Attributes = a.Attributes.ToSpec()
103124

internal/mapper/datasource_mapper.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package mapper
66
import (
77
"fmt"
88
"log/slog"
9+
"strings"
910

1011
"github.com/hashicorp/terraform-plugin-codegen-openapi/internal/config"
1112
"github.com/hashicorp/terraform-plugin-codegen-openapi/internal/explorer"
@@ -106,7 +107,6 @@ func generateDataSourceSchema(logger *slog.Logger, name string, dataSource explo
106107
// ****************
107108
// READ Parameters (optional)
108109
// ****************
109-
readParameterAttributes := attrmapper.DataSourceAttributes{}
110110
if dataSource.ReadOp != nil && dataSource.ReadOp.Parameters != nil {
111111
for _, param := range dataSource.ReadOp.Parameters {
112112
if param.In != util.OAS_param_path && param.In != util.OAS_param_query {
@@ -141,18 +141,21 @@ func generateDataSourceSchema(logger *slog.Logger, name string, dataSource explo
141141
continue
142142
}
143143

144-
parameterAttribute, schemaErr := s.BuildDataSourceAttribute(paramName, computability)
144+
paramPath := strings.Split(paramName, ".")
145+
146+
parameterAttribute, schemaErr := s.BuildDataSourceAttribute(paramPath[len(paramPath)-1], computability)
145147
if schemaErr != nil {
146148
log.WarnLogOnError(pLogger, schemaErr, "skipping mapping of read operation parameter")
147149
continue
148150
}
149151

150-
readParameterAttributes = append(readParameterAttributes, parameterAttribute)
152+
// TODO: currently, no errors can be returned from merging, but in the future we should consider raising errors/warnings for unexpected scenarios, like type mismatches between attribute schemas
153+
readResponseAttributes, _ = readResponseAttributes.MergeAttribute(paramPath, parameterAttribute, computability)
151154
}
152155
}
153156

154157
// TODO: currently, no errors can be returned from merging, but in the future we should consider raising errors/warnings for unexpected scenarios, like type mismatches between attribute schemas
155-
dataSourceAttributes, _ := readParameterAttributes.Merge(readResponseAttributes)
158+
dataSourceAttributes := readResponseAttributes
156159

157160
// TODO: handle error for overrides
158161
dataSourceAttributes, _ = dataSourceAttributes.ApplyOverrides(dataSource.SchemaOptions.AttributeOptions.Overrides)

internal/mapper/resource_mapper.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package mapper
66
import (
77
"errors"
88
"log/slog"
9+
"strings"
910

1011
"github.com/hashicorp/terraform-plugin-codegen-openapi/internal/config"
1112
"github.com/hashicorp/terraform-plugin-codegen-openapi/internal/explorer"
@@ -140,7 +141,6 @@ func generateResourceSchema(logger *slog.Logger, explorerResource explorer.Resou
140141
// ****************
141142
// READ Parameters (optional)
142143
// ****************
143-
readParameterAttributes := attrmapper.ResourceAttributes{}
144144
if explorerResource.ReadOp != nil && explorerResource.ReadOp.Parameters != nil {
145145
for _, param := range explorerResource.ReadOp.Parameters {
146146
if param.In != util.OAS_param_path && param.In != util.OAS_param_query {
@@ -171,18 +171,21 @@ func generateResourceSchema(logger *slog.Logger, explorerResource explorer.Resou
171171
continue
172172
}
173173

174-
parameterAttribute, schemaErr := s.BuildResourceAttribute(paramName, schema.ComputedOptional)
174+
paramPath := strings.Split(paramName, ".")
175+
176+
parameterAttribute, schemaErr := s.BuildResourceAttribute(paramPath[len(paramPath)-1], schema.ComputedOptional)
175177
if schemaErr != nil {
176178
log.WarnLogOnError(pLogger, schemaErr, "skipping mapping of read operation parameter")
177179
continue
178180
}
179181

180-
readParameterAttributes = append(readParameterAttributes, parameterAttribute)
182+
// TODO: currently, no errors can be returned from merging, but in the future we should consider raising errors/warnings for unexpected scenarios, like type mismatches between attribute schemas
183+
readResponseAttributes, _ = readResponseAttributes.MergeAttribute(paramPath, parameterAttribute, schema.ComputedOptional)
181184
}
182185
}
183186

184187
// TODO: currently, no errors can be returned from merging, but in the future we should consider raising errors/warnings for unexpected scenarios, like type mismatches between attribute schemas
185-
resourceAttributes, _ := createRequestAttributes.Merge(createResponseAttributes, readResponseAttributes, readParameterAttributes)
188+
resourceAttributes, _ := createRequestAttributes.Merge(createResponseAttributes, readResponseAttributes)
186189

187190
// TODO: handle error for overrides
188191
resourceAttributes, _ = resourceAttributes.ApplyOverrides(explorerResource.SchemaOptions.AttributeOptions.Overrides)

0 commit comments

Comments
 (0)