lang/eval: Apply attr-as-nested-block fixup in EvalBlock
For any block content we evaluate dynamically via this API, we'll make a special allowance for users to optionally write members of a list attribute instead as a sequence of nested blocks, thus allowing some existing provider features that were assuming this capability to continue to support it after v0.12. This should not be used for any new provider features, and should ideally be eventually phased out so that there aren't two similar-but-slightly-different syntaxes for saying the same thing.
This commit is contained in:
parent
6dcf8195b8
commit
87786484ea
|
@ -43,6 +43,41 @@ resource "test_resource_config_mode" "foo" {
|
||||||
},
|
},
|
||||||
resource.TestStep{
|
resource.TestStep{
|
||||||
Config: strings.TrimSpace(`
|
Config: strings.TrimSpace(`
|
||||||
|
resource "test_resource_config_mode" "foo" {
|
||||||
|
# Due to a preprocessing fixup we do in lang.EvalBlock, it's allowed
|
||||||
|
# to specify resource_as_attr members using one or more nested blocks
|
||||||
|
# instead of attribute syntax, if desired. This should be equivalent
|
||||||
|
# to the previous config.
|
||||||
|
#
|
||||||
|
# This allowance is made for backward-compatibility with existing providers
|
||||||
|
# before Terraform v0.12 that were expecting nested block types to also
|
||||||
|
# support attribute syntax; it should not be used for any new use-cases.
|
||||||
|
resource_as_attr {
|
||||||
|
foo = "resource_as_attr 0"
|
||||||
|
}
|
||||||
|
resource_as_attr {
|
||||||
|
foo = "resource_as_attr 1"
|
||||||
|
}
|
||||||
|
resource_as_attr_dynamic = [
|
||||||
|
{
|
||||||
|
foo = "resource_as_attr_dynamic 0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
`),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
resource.TestCheckResourceAttr("test_resource_config_mode.foo", "resource_as_attr.#", "2"),
|
||||||
|
resource.TestCheckResourceAttr("test_resource_config_mode.foo", "resource_as_attr.0.foo", "resource_as_attr 0"),
|
||||||
|
resource.TestCheckResourceAttr("test_resource_config_mode.foo", "resource_as_attr.1.foo", "resource_as_attr 1"),
|
||||||
|
resource.TestCheckResourceAttr("test_resource_config_mode.foo", "resource_as_attr_dynamic.#", "2"),
|
||||||
|
resource.TestCheckResourceAttr("test_resource_config_mode.foo", "resource_as_attr_dynamic.0.foo", "resource_as_attr_dynamic 0"),
|
||||||
|
resource.TestCheckResourceAttr("test_resource_config_mode.foo", "resource_as_attr_dynamic.1.foo", "default"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
resource.TestStep{
|
||||||
|
Config: strings.TrimSpace(`
|
||||||
resource "test_resource_config_mode" "foo" {
|
resource "test_resource_config_mode" "foo" {
|
||||||
resource_as_attr = [
|
resource_as_attr = [
|
||||||
{
|
{
|
||||||
|
|
12
lang/eval.go
12
lang/eval.go
|
@ -5,12 +5,12 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/addrs"
|
|
||||||
|
|
||||||
"github.com/hashicorp/hcl2/ext/dynblock"
|
"github.com/hashicorp/hcl2/ext/dynblock"
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl2/hcl"
|
||||||
"github.com/hashicorp/hcl2/hcldec"
|
"github.com/hashicorp/hcl2/hcldec"
|
||||||
|
"github.com/hashicorp/terraform/addrs"
|
||||||
"github.com/hashicorp/terraform/configs/configschema"
|
"github.com/hashicorp/terraform/configs/configschema"
|
||||||
|
"github.com/hashicorp/terraform/lang/blocktoattr"
|
||||||
"github.com/hashicorp/terraform/tfdiags"
|
"github.com/hashicorp/terraform/tfdiags"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
"github.com/zclconf/go-cty/cty/convert"
|
"github.com/zclconf/go-cty/cty/convert"
|
||||||
|
@ -58,6 +58,14 @@ func (s *Scope) EvalBlock(body hcl.Body, schema *configschema.Block) (cty.Value,
|
||||||
return cty.UnknownVal(schema.ImpliedType()), diags
|
return cty.UnknownVal(schema.ImpliedType()), diags
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HACK: In order to remain compatible with some assumptions made in
|
||||||
|
// Terraform v0.11 and earlier about the approximate equivalence of
|
||||||
|
// attribute vs. block syntax, we do a just-in-time fixup here to allow
|
||||||
|
// any attribute in the schema that has a list-of-objects or set-of-objects
|
||||||
|
// kind to potentially be populated instead by one or more nested blocks
|
||||||
|
// whose type is the attribute name.
|
||||||
|
body = blocktoattr.FixUpBlockAttrs(body, schema)
|
||||||
|
|
||||||
val, evalDiags := hcldec.Decode(body, spec, ctx)
|
val, evalDiags := hcldec.Decode(body, spec, ctx)
|
||||||
diags = diags.Append(evalDiags)
|
diags = diags.Append(evalDiags)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue