Skip to content

Commit

Permalink
refine the skipFixup heuristic
Browse files Browse the repository at this point in the history
We can also rule out some attribute types as indicating something other
than the legacy SDK.

- Tuple types were not generated at all.
- There were no single objects types, the convention was to use a block
  list or set of length 1.
- Maps of objects were not possible to generate, since named blocks were
  not implemented.
- Nested collections were not supported, but when they were generated they
  would have primitive types.
  • Loading branch information
jbardin committed Sep 22, 2021
1 parent 6b4e73a commit 8706a18
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 4 deletions.
34 changes: 31 additions & 3 deletions internal/lang/blocktoattr/fixup.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package blocktoattr

import (
"log"

"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hcldec"
"github.com/hashicorp/terraform/internal/configs/configschema"
Expand Down Expand Up @@ -33,6 +35,10 @@ func FixUpBlockAttrs(body hcl.Body, schema *configschema.Block) hcl.Body {
}

if skipFixup(schema) {
// we don't have any context for the resource name or type, but
// hopefully this could help locate the evaluation in the logs if there
// were a problem
log.Println("[DEBUG] skipping FixUpBlockAttrs")
return body
}

Expand All @@ -43,14 +49,36 @@ func FixUpBlockAttrs(body hcl.Body, schema *configschema.Block) hcl.Body {
}
}

// skipFixup detects any use of Attribute.NestedType. Because the fixup was
// only supported for the legacy SDK, there is no situation where structural
// attributes are used where the fixup is expected.
// skipFixup detects any use of Attribute.NestedType, or Types which could not
// be generate by the legacy SDK when taking SchemaConfigModeAttr into account.
func skipFixup(schema *configschema.Block) bool {
for _, attr := range schema.Attributes {
if attr.NestedType != nil {
return true
}
ty := attr.Type

// Lists and sets of objects could be generated by
// SchemaConfigModeAttr, but some other combinations can be ruled out.

// Tuples and objects could not be generated at all.
if ty.IsTupleType() || ty.IsObjectType() {
return true
}

// A map of objects was not possible.
if ty.IsMapType() && ty.ElementType().IsObjectType() {
return true
}

// Nested collections were not really supported, but could be generated
// with string types (though we conservatively limit this to primitive types)
if ty.IsCollectionType() {
ety := ty.ElementType()
if ety.IsCollectionType() && !ety.ElementType().IsPrimitiveType() {
return true
}
}
}

for _, block := range schema.BlockTypes {
Expand Down
34 changes: 33 additions & 1 deletion internal/lang/blocktoattr/fixup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ container {
}),
wantErrs: true,
},
"no fixup allowed": {
"no fixup allowed with NestedType": {
src: `
container {
foo = "one"
Expand Down Expand Up @@ -429,6 +429,38 @@ container {
}),
wantErrs: true,
},
"no fixup allowed new types": {
src: `
container {
foo = "one"
}
`,
schema: &configschema.Block{
Attributes: map[string]*configschema.Attribute{
// This could be a ConfigModeAttr fixup
"container": {
Type: cty.List(cty.Object(map[string]cty.Type{
"foo": cty.String,
})),
},
// But the presence of this type means it must have been
// declared by a new SDK
"new_type": {
Type: cty.Object(map[string]cty.Type{
"boo": cty.String,
}),
},
},
},
want: cty.ObjectVal(map[string]cty.Value{
"container": cty.NullVal(cty.List(
cty.Object(map[string]cty.Type{
"foo": cty.String,
}),
)),
}),
wantErrs: true,
},
}

ctx := &hcl.EvalContext{
Expand Down

0 comments on commit 8706a18

Please sign in to comment.