skip the blocktoattr fixup with nested types

If structural types are being used, we can be assured that the legacy
SDK SchemaConfigModeAttr is not being used, and the fixup is not needed.

This prevents inadvertent mapping of blocks to structural attributes,
and allows us to skip the fixup overhead when possible.
This commit is contained in:
James Bardin 2021-09-22 12:09:26 -04:00
parent 08a86b6c13
commit 6b4e73af48
2 changed files with 56 additions and 0 deletions

View File

@ -12,6 +12,10 @@ import (
// type in the schema to be written with HCL block syntax as multiple nested
// blocks with the attribute name as the block type.
//
// The fixup is only applied in the absence of structural attribute types. The
// presence of these types indicate the use of a provider which does not
// support mapping blocks to attributes.
//
// This partially restores some of the block/attribute confusion from HCL 1
// so that existing patterns that depended on that confusion can continue to
// be used in the short term while we settle on a longer-term strategy.
@ -28,6 +32,10 @@ func FixUpBlockAttrs(body hcl.Body, schema *configschema.Block) hcl.Body {
schema = &configschema.Block{}
}
if skipFixup(schema) {
return body
}
return &fixupBody{
original: body,
schema: schema,
@ -35,6 +43,25 @@ 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.
func skipFixup(schema *configschema.Block) bool {
for _, attr := range schema.Attributes {
if attr.NestedType != nil {
return true
}
}
for _, block := range schema.BlockTypes {
if skipFixup(&block.Block) {
return true
}
}
return false
}
type fixupBody struct {
original hcl.Body
schema *configschema.Block

View File

@ -400,6 +400,35 @@ container {
}),
wantErrs: true,
},
"no fixup allowed": {
src: `
container {
foo = "one"
}
`,
schema: &configschema.Block{
Attributes: map[string]*configschema.Attribute{
"container": {
NestedType: &configschema.Object{
Nesting: configschema.NestingList,
Attributes: map[string]*configschema.Attribute{
"foo": {
Type: 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{