From 05e85885f95716318a5884fae2a56d254d6e3023 Mon Sep 17 00:00:00 2001 From: James Bardin Date: Mon, 23 Jul 2018 22:30:41 -0400 Subject: [PATCH] handle Null collections in flatmaps When creating a flatmap from a cty.Value, there may be Null collections which don't need to be added to the flatmap at all. Skip over these to avoid panicking in ElementIterator with a Null value. --- config/hcl2shim/flatmap.go | 8 ++++ config/hcl2shim/flatmap_test.go | 67 +++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/config/hcl2shim/flatmap.go b/config/hcl2shim/flatmap.go index 5a40b9eccc..6b9a52dbc9 100644 --- a/config/hcl2shim/flatmap.go +++ b/config/hcl2shim/flatmap.go @@ -68,6 +68,10 @@ func flatmapValueFromHCL2Primitive(m map[string]string, key string, val cty.Valu } func flatmapValueFromHCL2Map(m map[string]string, prefix string, val cty.Value) { + if val.IsNull() { + // Omit entirely + return + } if !val.IsKnown() { switch { case val.Type().IsObjectType(): @@ -95,6 +99,10 @@ func flatmapValueFromHCL2Map(m map[string]string, prefix string, val cty.Value) } func flatmapValueFromHCL2Seq(m map[string]string, prefix string, val cty.Value) { + if val.IsNull() { + // Omit entirely + return + } if !val.IsKnown() { m[prefix+"#"] = UnknownVariableValue return diff --git a/config/hcl2shim/flatmap_test.go b/config/hcl2shim/flatmap_test.go index abad07e6a2..affd8dbf5b 100644 --- a/config/hcl2shim/flatmap_test.go +++ b/config/hcl2shim/flatmap_test.go @@ -249,6 +249,73 @@ func TestFlatmapValueFromHCL2(t *testing.T) { } } +func TestFlatmapValueFromHCL2FromFlatmap(t *testing.T) { + tests := []struct { + Name string + Map map[string]string + Type cty.Type + }{ + { + "empty flatmap with collections", + map[string]string{}, + cty.Object(map[string]cty.Type{ + "foo": cty.Map(cty.String), + "bar": cty.Set(cty.String), + }), + }, + { + "nil flatmap with collections", + nil, + cty.Object(map[string]cty.Type{ + "foo": cty.Map(cty.String), + "bar": cty.Set(cty.String), + }), + }, + { + "empty flatmap with nested collections", + map[string]string{}, + cty.Object(map[string]cty.Type{ + "foo": cty.Object( + map[string]cty.Type{ + "baz": cty.Map(cty.String), + }, + ), + "bar": cty.Set(cty.String), + }), + }, + { + "partial flatmap with nested collections", + map[string]string{ + "foo.baz.%": "1", + "foo.baz.key": "val", + }, + cty.Object(map[string]cty.Type{ + "foo": cty.Object( + map[string]cty.Type{ + "baz": cty.Map(cty.String), + "biz": cty.Map(cty.String), + }, + ), + "bar": cty.Set(cty.String), + }), + }, + } + + for _, test := range tests { + t.Run(test.Name, func(t *testing.T) { + val, err := HCL2ValueFromFlatmap(test.Map, test.Type) + if err != nil { + t.Fatal(err) + } + + got := FlatmapValueFromHCL2(val) + + for _, problem := range deep.Equal(got, test.Map) { + t.Error(problem) + } + }) + } +} func TestHCL2ValueFromFlatmap(t *testing.T) { tests := []struct { Flatmap map[string]string