From 107c1cdb09c575aa2f61d97f48d8587eb6bada4c Mon Sep 17 00:00:00 2001 From: Nathan Dench Date: Fri, 24 May 2019 15:16:44 +1000 Subject: Upgrade to 0.12 --- .../hashicorp/terraform/config/hcl2shim/values.go | 109 ++++++++++++++++++++- 1 file changed, 108 insertions(+), 1 deletion(-) (limited to 'vendor/github.com/hashicorp/terraform/config/hcl2shim/values.go') diff --git a/vendor/github.com/hashicorp/terraform/config/hcl2shim/values.go b/vendor/github.com/hashicorp/terraform/config/hcl2shim/values.go index 0b697a5..daeb0b8 100644 --- a/vendor/github.com/hashicorp/terraform/config/hcl2shim/values.go +++ b/vendor/github.com/hashicorp/terraform/config/hcl2shim/values.go @@ -6,6 +6,8 @@ import ( "github.com/hashicorp/hil/ast" "github.com/zclconf/go-cty/cty" + + "github.com/hashicorp/terraform/configs/configschema" ) // UnknownVariableValue is a sentinel value that can be used @@ -14,6 +16,108 @@ import ( // unknown keys. const UnknownVariableValue = "74D93920-ED26-11E3-AC10-0800200C9A66" +// ConfigValueFromHCL2Block is like ConfigValueFromHCL2 but it works only for +// known object values and uses the provided block schema to perform some +// additional normalization to better mimic the shape of value that the old +// HCL1/HIL-based codepaths would've produced. +// +// In particular, it discards the collections that we use to represent nested +// blocks (other than NestingSingle) if they are empty, which better mimics +// the HCL1 behavior because HCL1 had no knowledge of the schema and so didn't +// know that an unspecified block _could_ exist. +// +// The given object value must conform to the schema's implied type or this +// function will panic or produce incorrect results. +// +// This is primarily useful for the final transition from new-style values to +// terraform.ResourceConfig before calling to a legacy provider, since +// helper/schema (the old provider SDK) is particularly sensitive to these +// subtle differences within its validation code. +func ConfigValueFromHCL2Block(v cty.Value, schema *configschema.Block) map[string]interface{} { + if v.IsNull() { + return nil + } + if !v.IsKnown() { + panic("ConfigValueFromHCL2Block used with unknown value") + } + if !v.Type().IsObjectType() { + panic(fmt.Sprintf("ConfigValueFromHCL2Block used with non-object value %#v", v)) + } + + atys := v.Type().AttributeTypes() + ret := make(map[string]interface{}) + + for name := range schema.Attributes { + if _, exists := atys[name]; !exists { + continue + } + + av := v.GetAttr(name) + if av.IsNull() { + // Skip nulls altogether, to better mimic how HCL1 would behave + continue + } + ret[name] = ConfigValueFromHCL2(av) + } + + for name, blockS := range schema.BlockTypes { + if _, exists := atys[name]; !exists { + continue + } + bv := v.GetAttr(name) + if !bv.IsKnown() { + ret[name] = UnknownVariableValue + continue + } + if bv.IsNull() { + continue + } + + switch blockS.Nesting { + + case configschema.NestingSingle, configschema.NestingGroup: + ret[name] = ConfigValueFromHCL2Block(bv, &blockS.Block) + + case configschema.NestingList, configschema.NestingSet: + l := bv.LengthInt() + if l == 0 { + // skip empty collections to better mimic how HCL1 would behave + continue + } + + elems := make([]interface{}, 0, l) + for it := bv.ElementIterator(); it.Next(); { + _, ev := it.Element() + if !ev.IsKnown() { + elems = append(elems, UnknownVariableValue) + continue + } + elems = append(elems, ConfigValueFromHCL2Block(ev, &blockS.Block)) + } + ret[name] = elems + + case configschema.NestingMap: + if bv.LengthInt() == 0 { + // skip empty collections to better mimic how HCL1 would behave + continue + } + + elems := make(map[string]interface{}) + for it := bv.ElementIterator(); it.Next(); { + ek, ev := it.Element() + if !ev.IsKnown() { + elems[ek.AsString()] = UnknownVariableValue + continue + } + elems[ek.AsString()] = ConfigValueFromHCL2Block(ev, &blockS.Block) + } + ret[name] = elems + } + } + + return ret +} + // ConfigValueFromHCL2 converts a value from HCL2 (really, from the cty dynamic // types library that HCL2 uses) to a value type that matches what would've // been produced from the HCL-based interpolator for an equivalent structure. @@ -73,7 +177,10 @@ func ConfigValueFromHCL2(v cty.Value) interface{} { it := v.ElementIterator() for it.Next() { ek, ev := it.Element() - l[ek.AsString()] = ConfigValueFromHCL2(ev) + cv := ConfigValueFromHCL2(ev) + if cv != nil { + l[ek.AsString()] = cv + } } return l } -- cgit v1.2.3