Skip to content

Commit

Permalink
chore: PoC - Schema code generation - Supporting nested attributes (#…
Browse files Browse the repository at this point in the history
…2689)

* support nested attribute types

* rebasing changes related to unit testing adjustment
  • Loading branch information
AgustinBettati authored Oct 16, 2024
1 parent 14e3671 commit 8ddd508
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 28 deletions.
7 changes: 2 additions & 5 deletions tools/codegen/codespec/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,6 @@ type MapNestedAttribute struct {
type NumberAttribute struct {
Default *CustomDefault
}
type ObjectAttribute struct {
Default *CustomDefault
}
type SetAttribute struct {
Default *CustomDefault
ElementType ElemType
Expand All @@ -83,8 +80,8 @@ type SetNestedAttribute struct {
NestedObject NestedAttributeObject
}
type SingleNestedAttribute struct {
Default *CustomDefault
Attributes Attributes
Default *CustomDefault
NestedObject NestedAttributeObject
}
type StringAttribute struct {
Default *string
Expand Down
3 changes: 2 additions & 1 deletion tools/codegen/schema/codetemplate/schema-file.go.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import (

func ResourceSchema(ctx context.Context) schema.Schema {
return schema.Schema{
Attributes: map[string]schema.Attribute{ {{ range .SchemaAttributes }}{{ . }}{{- end }}
Attributes: map[string]schema.Attribute{
{{ .SchemaAttributes }}
},
}
}
2 changes: 1 addition & 1 deletion tools/codegen/schema/codetemplate/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ var schemaFileTemplate string

type SchemaFileInputs struct {
PackageName string
SchemaAttributes string
Imports []string
SchemaAttributes []string
}

func ApplySchemaFileTemplate(inputs SchemaFileInputs) bytes.Buffer {
Expand Down
22 changes: 14 additions & 8 deletions tools/codegen/schema/schema_attribute.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,22 @@ type CodeStatement struct {
Imports []string
}

func GenerateSchemaAttributes(attrs codespec.Attributes) []CodeStatement {
result := []CodeStatement{}
func GenerateSchemaAttributes(attrs codespec.Attributes) CodeStatement {
attrsCode := []string{}
imports := []string{}
for i := range attrs {
result = append(result, attribute(&attrs[i]))
result := generateAttribute(&attrs[i])
attrsCode = append(attrsCode, result.Result)
imports = append(imports, result.Imports...)
}
finalAttrs := strings.Join(attrsCode, ",\n") + ","
return CodeStatement{
Result: finalAttrs,
Imports: imports,
}
return result
}

func attribute(attr *codespec.Attribute) CodeStatement {
func generateAttribute(attr *codespec.Attribute) CodeStatement {
generator := typeGenerator(attr)

typeDefinition := generator.TypeDefinition()
Expand All @@ -35,10 +42,9 @@ func attribute(attr *codespec.Attribute) CodeStatement {

name := attr.Name
propsResultString := strings.Join(properties, ",\n") + ","
code := fmt.Sprintf(`
"%s": %s{
code := fmt.Sprintf(`"%s": %s{
%s
},`, name, typeDefinition, propsResultString)
}`, name, typeDefinition, propsResultString)
return CodeStatement{
Result: code,
Imports: imports,
Expand Down
10 changes: 2 additions & 8 deletions tools/codegen/schema/schema_file.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,11 @@ import (

func GenerateGoCode(input genconfigmapper.Resource) string {
schemaAttrs := GenerateSchemaAttributes(input.Schema.Attributes)
attrsCode := []string{}
imports := []string{}
for _, attr := range schemaAttrs {
attrsCode = append(attrsCode, attr.Result)
imports = append(imports, attr.Imports...)
}

tmplInputs := codetemplate.SchemaFileInputs{
PackageName: input.Name,
Imports: imports,
SchemaAttributes: attrsCode,
Imports: schemaAttrs.Imports,
SchemaAttributes: schemaAttrs.Result,
}
result := codetemplate.ApplySchemaFileTemplate(tmplInputs)

Expand Down
53 changes: 53 additions & 0 deletions tools/codegen/schema/schema_file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ import (
"go.mongodb.org/atlas-sdk/v20240530005/admin"
)

var stringAttr = codespec.Attribute{
Name: "string_attr",
String: &codespec.StringAttribute{},
Description: admin.PtrString("string attribute"),
ComputedOptionalRequired: codespec.Optional,
}

type schemaGenerationTestCase struct {
inputModel codespec.Resource
goldenFileName string
Expand Down Expand Up @@ -80,6 +87,52 @@ func TestSchemaGenerationFromCodeSpec(t *testing.T) {
},
goldenFileName: "primitive-attributes",
},
"Nested attributes": {
inputModel: codespec.Resource{
Name: "test_name",
Schema: &codespec.Schema{
Attributes: []codespec.Attribute{
{
Name: "nested_single_attr",
Description: admin.PtrString("nested single attribute"),
ComputedOptionalRequired: codespec.Required,
SingleNested: &codespec.SingleNestedAttribute{
NestedObject: codespec.NestedAttributeObject{
Attributes: []codespec.Attribute{
stringAttr,
},
},
},
},
{
Name: "nested_list_attr",
Description: admin.PtrString("nested list attribute"),
ComputedOptionalRequired: codespec.Optional,
ListNested: &codespec.ListNestedAttribute{
NestedObject: codespec.NestedAttributeObject{
Attributes: []codespec.Attribute{
stringAttr,
},
},
},
},
{
Name: "set_nested_attribute",
Description: admin.PtrString("set nested attribute"),
ComputedOptionalRequired: codespec.ComputedOptional,
SetNested: &codespec.SetNestedAttribute{
NestedObject: codespec.NestedAttributeObject{
Attributes: []codespec.Attribute{
stringAttr,
},
},
},
},
},
},
},
goldenFileName: "nested-attributes",
},
}

for testName, tc := range testCases {
Expand Down
25 changes: 20 additions & 5 deletions tools/codegen/schema/schema_nested_attribute.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package schema

import "github.com/mongodb/terraform-provider-mongodbatlas/tools/codegen/codespec"
import (
"fmt"

"github.com/mongodb/terraform-provider-mongodbatlas/tools/codegen/codespec"
)

type ListNestedAttrGenerator struct {
model codespec.ListNestedAttribute
Expand All @@ -11,7 +15,7 @@ func (l *ListNestedAttrGenerator) TypeDefinition() string {
}

func (l *ListNestedAttrGenerator) TypeSpecificProperties() []CodeStatement {
return nil
return []CodeStatement{getPropertyForNestedObj(l.model.NestedObject)}
}

type SetNestedGenerator struct {
Expand All @@ -23,7 +27,7 @@ func (s *SetNestedGenerator) TypeDefinition() string {
}

func (s *SetNestedGenerator) TypeSpecificProperties() []CodeStatement {
return nil
return []CodeStatement{getPropertyForNestedObj(s.model.NestedObject)}
}

type MapNestedAttrGenerator struct {
Expand All @@ -35,7 +39,7 @@ func (m *MapNestedAttrGenerator) TypeDefinition() string {
}

func (m *MapNestedAttrGenerator) TypeSpecificProperties() []CodeStatement {
return nil
return []CodeStatement{getPropertyForNestedObj(m.model.NestedObject)}
}

type SingleNestedAttrGenerator struct {
Expand All @@ -47,5 +51,16 @@ func (s *SingleNestedAttrGenerator) TypeDefinition() string {
}

func (s *SingleNestedAttrGenerator) TypeSpecificProperties() []CodeStatement {
return nil
return []CodeStatement{getPropertyForNestedObj(s.model.NestedObject)}
}

func getPropertyForNestedObj(nested codespec.NestedAttributeObject) CodeStatement {
attrs := GenerateSchemaAttributes(nested.Attributes)
attributeProperty := fmt.Sprintf(`Attributes: map[string]schema.Attribute{
%s
}`, attrs.Result)
return CodeStatement{
Result: attributeProperty,
Imports: attrs.Imports,
}
}
45 changes: 45 additions & 0 deletions tools/codegen/schema/testdata/nested-attributes.golden.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package test_name

import (
"context"

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

func ResourceSchema(ctx context.Context) schema.Schema {
return schema.Schema{
Attributes: map[string]schema.Attribute{
"nested_single_attr": schema.SingleNestedAttribute{
Required: true,
MarkdownDescription: "nested single attribute",
Attributes: map[string]schema.Attribute{
"string_attr": schema.StringAttribute{
Optional: true,
MarkdownDescription: "string attribute",
},
},
},
"nested_list_attr": schema.ListNestedAttribute{
Optional: true,
MarkdownDescription: "nested list attribute",
Attributes: map[string]schema.Attribute{
"string_attr": schema.StringAttribute{
Optional: true,
MarkdownDescription: "string attribute",
},
},
},
"set_nested_attribute": schema.SetNestedAttribute{
Computed: true,
Optional: true,
MarkdownDescription: "set nested attribute",
Attributes: map[string]schema.Attribute{
"string_attr": schema.StringAttribute{
Optional: true,
MarkdownDescription: "string attribute",
},
},
},
},
}
}

0 comments on commit 8ddd508

Please sign in to comment.