don't set Unknown for computed values

Any value that is not set in the configuration should decode as a Null
value. Unknown should still be returned if a computed value expression
is unknown.
This commit is contained in:
James Bardin 2018-07-20 12:40:22 -04:00 committed by Martin Atkins
parent d8bf3cc4e0
commit 50e099ad10
2 changed files with 18 additions and 30 deletions

View File

@ -2,7 +2,6 @@ package configschema
import (
"github.com/hashicorp/hcl2/hcldec"
"github.com/zclconf/go-cty/cty"
)
var mapLabelNames = []string{"key"}
@ -11,9 +10,8 @@ var mapLabelNames = []string{"key"}
// using the facilities in the hcldec package.
//
// The returned specification is guaranteed to return a value of the same type
// returned by method ImpliedType, but it may contain null or unknown values if
// any of the block attributes are defined as optional and/or computed
// respectively.
// returned by method ImpliedType, but it may contain null values if any of the
// block attributes are defined as optional and/or computed respectively.
func (b *Block) DecoderSpec() hcldec.Spec {
ret := hcldec.ObjectSpec{}
if b == nil {
@ -21,32 +19,12 @@ func (b *Block) DecoderSpec() hcldec.Spec {
}
for name, attrS := range b.Attributes {
switch {
case attrS.Computed && attrS.Optional:
// In this special case we use an unknown value as a default
// to get the intended behavior that the result is computed
// unless it has been explicitly set in config.
ret[name] = &hcldec.DefaultSpec{
Primary: &hcldec.AttrSpec{
Name: name,
Type: attrS.Type,
},
Default: &hcldec.LiteralSpec{
Value: cty.UnknownVal(attrS.Type),
},
}
case attrS.Computed:
ret[name] = &hcldec.LiteralSpec{
Value: cty.UnknownVal(attrS.Type),
}
default:
ret[name] = &hcldec.AttrSpec{
Name: name,
Type: attrS.Type,
Required: attrS.Required,
}
}
}
for name, blockS := range b.BlockTypes {
if _, exists := ret[name]; exists {

View File

@ -55,6 +55,11 @@ func TestBlockDecoderSpec(t *testing.T) {
Optional: true,
Computed: true,
},
"optional_computed_unknown": {
Type: cty.String,
Optional: true,
Computed: true,
},
},
},
hcltest.MockBody(&hcl.BodyContent{
@ -67,14 +72,19 @@ func TestBlockDecoderSpec(t *testing.T) {
Name: "optional_computed_overridden",
Expr: hcltest.MockExprLiteral(cty.True),
},
"optional_computed_unknown": {
Name: "optional_computed_overridden",
Expr: hcltest.MockExprLiteral(cty.UnknownVal(cty.String)),
},
},
}),
cty.ObjectVal(map[string]cty.Value{
"optional": cty.NullVal(cty.Number),
"required": cty.StringVal("5"), // converted from number to string
"computed": cty.UnknownVal(cty.List(cty.Bool)),
"optional_computed": cty.UnknownVal(cty.Map(cty.Bool)),
"computed": cty.NullVal(cty.List(cty.Bool)),
"optional_computed": cty.NullVal(cty.Map(cty.Bool)),
"optional_computed_overridden": cty.True,
"optional_computed_unknown": cty.UnknownVal(cty.String),
}),
0,
},