From 6b4e73af48f1cb78e51a634b077f73548db39ddc Mon Sep 17 00:00:00 2001 From: James Bardin Date: Wed, 22 Sep 2021 12:09:26 -0400 Subject: [PATCH] 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. --- internal/lang/blocktoattr/fixup.go | 27 +++++++++++++++++++++++ internal/lang/blocktoattr/fixup_test.go | 29 +++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/internal/lang/blocktoattr/fixup.go b/internal/lang/blocktoattr/fixup.go index 1864e3e50..90eb260d7 100644 --- a/internal/lang/blocktoattr/fixup.go +++ b/internal/lang/blocktoattr/fixup.go @@ -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 diff --git a/internal/lang/blocktoattr/fixup_test.go b/internal/lang/blocktoattr/fixup_test.go index 8c7640521..92799394f 100644 --- a/internal/lang/blocktoattr/fixup_test.go +++ b/internal/lang/blocktoattr/fixup_test.go @@ -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{