vendor: upgrade go-cty dependency to 1.4.1 (#24983)
* vendor: upgrade go-cty dependency to 1.4.1 This upgrade fixes a panic with inconsistent object element types.
This commit is contained in:
parent
78d8af18c2
commit
a4c3c1d389
2
go.mod
2
go.mod
|
@ -121,7 +121,7 @@ require (
|
|||
github.com/xanzy/ssh-agent v0.2.1
|
||||
github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18 // indirect
|
||||
github.com/xlab/treeprint v0.0.0-20161029104018-1d6e34225557
|
||||
github.com/zclconf/go-cty v1.4.0
|
||||
github.com/zclconf/go-cty v1.4.1
|
||||
github.com/zclconf/go-cty-yaml v1.0.1
|
||||
go.uber.org/atomic v1.3.2 // indirect
|
||||
go.uber.org/multierr v1.1.0 // indirect
|
||||
|
|
2
go.sum
2
go.sum
|
@ -443,6 +443,8 @@ github.com/zclconf/go-cty v1.2.0 h1:sPHsy7ADcIZQP3vILvTjrh74ZA175TFP5vqiNK1UmlI=
|
|||
github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8=
|
||||
github.com/zclconf/go-cty v1.4.0 h1:+q+tmgyUB94HIdH/uVTIi/+kt3pt4sHwEZAcTyLoGsQ=
|
||||
github.com/zclconf/go-cty v1.4.0/go.mod h1:nHzOclRkoj++EU9ZjSrZvRG0BXIWt8c7loYc0qXAFGQ=
|
||||
github.com/zclconf/go-cty v1.4.1 h1:Xzr4m4utRDhHDifag1onwwUSq32HLoLBsp+w6tD0880=
|
||||
github.com/zclconf/go-cty v1.4.1/go.mod h1:nHzOclRkoj++EU9ZjSrZvRG0BXIWt8c7loYc0qXAFGQ=
|
||||
github.com/zclconf/go-cty-yaml v1.0.1 h1:up11wlgAaDvlAGENcFDnZgkn0qUJurso7k6EpURKNF8=
|
||||
github.com/zclconf/go-cty-yaml v1.0.1/go.mod h1:IP3Ylp0wQpYm50IHK8OZWKMu6sPJIUgKa8XhiVHura0=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
variable "foo" {
|
||||
default = 123
|
||||
}
|
||||
|
||||
resource "aws_instance" "foo" {
|
||||
foo = "${var.foo}"
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
variable "in" {}
|
||||
|
||||
resource "aws_instance" "mod" {
|
||||
value = "${var.in}"
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
resource "aws_instance" "foo" { }
|
||||
resource "aws_instance" "bar" { }
|
||||
|
||||
module "child" {
|
||||
source = "./child"
|
||||
in = "one,${aws_instance.foo.id},${aws_instance.bar.id}"
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
# Required
|
||||
variable "foo" {
|
||||
}
|
||||
|
||||
# Optional
|
||||
variable "bar" {
|
||||
default = "baz"
|
||||
}
|
||||
|
||||
# Mapping
|
||||
variable "map" {
|
||||
default = {
|
||||
foo = "bar"
|
||||
}
|
||||
}
|
||||
|
||||
# Complex Object Types
|
||||
variable "object_map" {
|
||||
type = map(object({
|
||||
foo = string,
|
||||
bar = any
|
||||
}))
|
||||
}
|
||||
|
||||
variable "object_list" {
|
||||
type = list(object({
|
||||
foo = string,
|
||||
bar = any
|
||||
}))
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
test = [
|
||||
{
|
||||
foo = "blah1"
|
||||
bar = {}
|
||||
},
|
||||
{
|
||||
foo = "blah2"
|
||||
bar = {
|
||||
var1 = "val1",
|
||||
var2 = "var2"
|
||||
}
|
||||
}
|
||||
]
|
|
@ -0,0 +1,30 @@
|
|||
# Required
|
||||
variable "foo" {
|
||||
}
|
||||
|
||||
# Optional
|
||||
variable "bar" {
|
||||
default = "baz"
|
||||
}
|
||||
|
||||
# Mapping
|
||||
variable "map" {
|
||||
default = {
|
||||
foo = "bar"
|
||||
}
|
||||
}
|
||||
|
||||
# Complex Object Types
|
||||
variable "object_map" {
|
||||
type = map(object({
|
||||
foo = string,
|
||||
bar = any
|
||||
}))
|
||||
}
|
||||
|
||||
variable "object_list" {
|
||||
type = list(object({
|
||||
foo = string,
|
||||
bar = any
|
||||
}))
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
variable "foo" {}
|
||||
variable "bar" {}
|
||||
|
||||
resource "aws_instance" "foo" {
|
||||
foo = "${var.foo}"
|
||||
bar = "${var.bar}"
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
variable "amis" {
|
||||
default = {
|
||||
us-west-2 = "bar"
|
||||
}
|
||||
}
|
||||
|
||||
variable "bar" {
|
||||
default = "baz"
|
||||
}
|
||||
|
||||
variable "foo" {}
|
||||
|
||||
resource "aws_instance" "foo" {
|
||||
num = "2"
|
||||
bar = var.bar
|
||||
}
|
||||
|
||||
resource "aws_instance" "bar" {
|
||||
foo = var.foo
|
||||
bar = var.amis[var.foo]
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
# Required
|
||||
variable "foo" {
|
||||
}
|
||||
|
||||
# Optional
|
||||
variable "bar" {
|
||||
default = "baz"
|
||||
}
|
||||
|
||||
# Mapping
|
||||
variable "map" {
|
||||
default = {
|
||||
foo = "bar"
|
||||
}
|
||||
}
|
|
@ -163,45 +163,120 @@ func TestVariables(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestSMCUserVariables(t *testing.T) {
|
||||
c := testModule(t, "smc-uservars")
|
||||
func TestCheckInputVariables(t *testing.T) {
|
||||
c := testModule(t, "input-variables")
|
||||
|
||||
// No variables set
|
||||
diags := checkInputVariables(c.Module.Variables, nil)
|
||||
if !diags.HasErrors() {
|
||||
t.Fatal("check succeeded, but want errors")
|
||||
}
|
||||
t.Run("No variables set", func(t *testing.T) {
|
||||
// No variables set
|
||||
diags := checkInputVariables(c.Module.Variables, nil)
|
||||
if !diags.HasErrors() {
|
||||
t.Fatal("check succeeded, but want errors")
|
||||
}
|
||||
|
||||
// Required variables set, optional variables unset
|
||||
// This is still an error at this layer, since it's the caller's
|
||||
// responsibility to have already merged in any default values.
|
||||
diags = checkInputVariables(c.Module.Variables, InputValues{
|
||||
"foo": &InputValue{
|
||||
Value: cty.StringVal("bar"),
|
||||
SourceType: ValueFromCLIArg,
|
||||
},
|
||||
// Required variables set, optional variables unset
|
||||
// This is still an error at this layer, since it's the caller's
|
||||
// responsibility to have already merged in any default values.
|
||||
diags = checkInputVariables(c.Module.Variables, InputValues{
|
||||
"foo": &InputValue{
|
||||
Value: cty.StringVal("bar"),
|
||||
SourceType: ValueFromCLIArg,
|
||||
},
|
||||
})
|
||||
if !diags.HasErrors() {
|
||||
t.Fatal("check succeeded, but want errors")
|
||||
}
|
||||
})
|
||||
if !diags.HasErrors() {
|
||||
t.Fatal("check succeeded, but want errors")
|
||||
}
|
||||
|
||||
// All variables set
|
||||
diags = checkInputVariables(c.Module.Variables, InputValues{
|
||||
"foo": &InputValue{
|
||||
Value: cty.StringVal("bar"),
|
||||
SourceType: ValueFromCLIArg,
|
||||
},
|
||||
"bar": &InputValue{
|
||||
Value: cty.StringVal("baz"),
|
||||
SourceType: ValueFromCLIArg,
|
||||
},
|
||||
"map": &InputValue{
|
||||
Value: cty.StringVal("baz"), // okay because config has no type constraint
|
||||
SourceType: ValueFromCLIArg,
|
||||
},
|
||||
t.Run("All variables set", func(t *testing.T) {
|
||||
diags := checkInputVariables(c.Module.Variables, InputValues{
|
||||
"foo": &InputValue{
|
||||
Value: cty.StringVal("bar"),
|
||||
SourceType: ValueFromCLIArg,
|
||||
},
|
||||
"bar": &InputValue{
|
||||
Value: cty.StringVal("baz"),
|
||||
SourceType: ValueFromCLIArg,
|
||||
},
|
||||
"map": &InputValue{
|
||||
Value: cty.StringVal("baz"), // okay because config has no type constraint
|
||||
SourceType: ValueFromCLIArg,
|
||||
},
|
||||
"object_map": &InputValue{
|
||||
Value: cty.MapVal(map[string]cty.Value{
|
||||
"uno": cty.ObjectVal(map[string]cty.Value{
|
||||
"foo": cty.StringVal("baz"),
|
||||
"bar": cty.NumberIntVal(2), // type = any
|
||||
}),
|
||||
"dos": cty.ObjectVal(map[string]cty.Value{
|
||||
"foo": cty.StringVal("bat"),
|
||||
"bar": cty.NumberIntVal(99), // type = any
|
||||
}),
|
||||
}),
|
||||
SourceType: ValueFromCLIArg,
|
||||
},
|
||||
"object_list": &InputValue{
|
||||
Value: cty.ListVal([]cty.Value{
|
||||
cty.ObjectVal(map[string]cty.Value{
|
||||
"foo": cty.StringVal("baz"),
|
||||
"bar": cty.NumberIntVal(2), // type = any
|
||||
}),
|
||||
cty.ObjectVal(map[string]cty.Value{
|
||||
"foo": cty.StringVal("bang"),
|
||||
"bar": cty.NumberIntVal(42), // type = any
|
||||
}),
|
||||
}),
|
||||
SourceType: ValueFromCLIArg,
|
||||
},
|
||||
})
|
||||
if diags.HasErrors() {
|
||||
t.Fatalf("unexpected errors: %s", diags.Err())
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Invalid Complex Types", func(t *testing.T) {
|
||||
diags := checkInputVariables(c.Module.Variables, InputValues{
|
||||
"foo": &InputValue{
|
||||
Value: cty.StringVal("bar"),
|
||||
SourceType: ValueFromCLIArg,
|
||||
},
|
||||
"bar": &InputValue{
|
||||
Value: cty.StringVal("baz"),
|
||||
SourceType: ValueFromCLIArg,
|
||||
},
|
||||
"map": &InputValue{
|
||||
Value: cty.StringVal("baz"), // okay because config has no type constraint
|
||||
SourceType: ValueFromCLIArg,
|
||||
},
|
||||
"object_map": &InputValue{
|
||||
Value: cty.MapVal(map[string]cty.Value{
|
||||
"uno": cty.ObjectVal(map[string]cty.Value{
|
||||
"foo": cty.StringVal("baz"),
|
||||
"bar": cty.NumberIntVal(2), // type = any
|
||||
}),
|
||||
"dos": cty.ObjectVal(map[string]cty.Value{
|
||||
"foo": cty.StringVal("bat"),
|
||||
"bar": cty.NumberIntVal(99), // type = any
|
||||
}),
|
||||
}),
|
||||
SourceType: ValueFromCLIArg,
|
||||
},
|
||||
"object_list": &InputValue{
|
||||
Value: cty.TupleVal([]cty.Value{
|
||||
cty.ObjectVal(map[string]cty.Value{
|
||||
"foo": cty.StringVal("baz"),
|
||||
"bar": cty.NumberIntVal(2), // type = any
|
||||
}),
|
||||
cty.ObjectVal(map[string]cty.Value{
|
||||
"foo": cty.StringVal("bang"),
|
||||
"bar": cty.StringVal("42"), // type = any, but mismatch with the first list item
|
||||
}),
|
||||
}),
|
||||
SourceType: ValueFromCLIArg,
|
||||
},
|
||||
})
|
||||
|
||||
if diags.HasErrors() {
|
||||
t.Fatalf("unexpected errors: %s", diags.Err())
|
||||
}
|
||||
})
|
||||
if diags.HasErrors() {
|
||||
//t.Fatal("check succeeded, but want errors")
|
||||
t.Fatalf("unexpected errors: %s", diags.Err())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -265,6 +265,7 @@ func conversionTupleToList(tupleType cty.Type, listEty cty.Type, unsafe bool) co
|
|||
// element conversions in elemConvs
|
||||
return func(val cty.Value, path cty.Path) (cty.Value, error) {
|
||||
elems := make([]cty.Value, 0, len(elemConvs))
|
||||
elemTys := make([]cty.Type, 0, len(elems))
|
||||
elemPath := append(path.Copy(), nil)
|
||||
i := int64(0)
|
||||
it := val.ElementIterator()
|
||||
|
@ -284,10 +285,15 @@ func conversionTupleToList(tupleType cty.Type, listEty cty.Type, unsafe bool) co
|
|||
}
|
||||
}
|
||||
elems = append(elems, val)
|
||||
elemTys = append(elemTys, val.Type())
|
||||
|
||||
i++
|
||||
}
|
||||
|
||||
elems, err := conversionUnifyListElements(elems, elemPath, unsafe)
|
||||
if err != nil {
|
||||
return cty.NilVal, err
|
||||
}
|
||||
return cty.ListVal(elems), nil
|
||||
}
|
||||
}
|
||||
|
@ -441,6 +447,7 @@ func conversionUnifyCollectionElements(elems map[string]cty.Value, path cty.Path
|
|||
}
|
||||
unifiedType, _ := unify(elemTypes, unsafe)
|
||||
if unifiedType == cty.NilType {
|
||||
return nil, path.NewErrorf("collection elements cannot be unified")
|
||||
}
|
||||
|
||||
unifiedElems := make(map[string]cty.Value)
|
||||
|
@ -486,3 +493,37 @@ func conversionCheckMapElementTypes(elems map[string]cty.Value, path cty.Path) e
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func conversionUnifyListElements(elems []cty.Value, path cty.Path, unsafe bool) ([]cty.Value, error) {
|
||||
elemTypes := make([]cty.Type, len(elems))
|
||||
for i, elem := range elems {
|
||||
elemTypes[i] = elem.Type()
|
||||
}
|
||||
unifiedType, _ := unify(elemTypes, unsafe)
|
||||
if unifiedType == cty.NilType {
|
||||
return nil, path.NewErrorf("collection elements cannot be unified")
|
||||
}
|
||||
|
||||
ret := make([]cty.Value, len(elems))
|
||||
elemPath := append(path.Copy(), nil)
|
||||
|
||||
for i, elem := range elems {
|
||||
if elem.Type().Equals(unifiedType) {
|
||||
ret[i] = elem
|
||||
continue
|
||||
}
|
||||
conv := getConversion(elem.Type(), unifiedType, unsafe)
|
||||
if conv == nil {
|
||||
}
|
||||
elemPath[len(elemPath)-1] = cty.IndexStep{
|
||||
Key: cty.NumberIntVal(int64(i)),
|
||||
}
|
||||
val, err := conv(elem, elemPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret[i] = val
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
|
|
@ -163,8 +163,23 @@ func SetSymmetricDifference(sets ...cty.Value) (cty.Value, error) {
|
|||
func setOperationReturnType(args []cty.Value) (ret cty.Type, err error) {
|
||||
var etys []cty.Type
|
||||
for _, arg := range args {
|
||||
etys = append(etys, arg.Type().ElementType())
|
||||
ty := arg.Type().ElementType()
|
||||
|
||||
// Do not unify types for empty dynamic pseudo typed collections. These
|
||||
// will always convert to any other concrete type.
|
||||
if arg.LengthInt() == 0 && ty.Equals(cty.DynamicPseudoType) {
|
||||
continue
|
||||
}
|
||||
|
||||
etys = append(etys, ty)
|
||||
}
|
||||
|
||||
// If all element types were skipped (due to being empty dynamic collections),
|
||||
// the return type should also be a set of dynamic pseudo type.
|
||||
if len(etys) == 0 {
|
||||
return cty.Set(cty.DynamicPseudoType), nil
|
||||
}
|
||||
|
||||
newEty, _ := convert.UnifyUnsafe(etys)
|
||||
if newEty == cty.NilType {
|
||||
return cty.NilType, fmt.Errorf("given sets must all have compatible element types")
|
||||
|
|
|
@ -196,3 +196,9 @@ func (r pathSetRules) Equivalent(a, b interface{}) bool {
|
|||
|
||||
return true
|
||||
}
|
||||
|
||||
// SameRules is true if both Rules instances are pathSetRules structs.
|
||||
func (r pathSetRules) SameRules(other set.Rules) bool {
|
||||
_, ok := other.(pathSetRules)
|
||||
return ok
|
||||
}
|
||||
|
|
|
@ -22,6 +22,10 @@ type Rules interface {
|
|||
// though it is *not* required that two values with the same hash value
|
||||
// be equivalent.
|
||||
Equivalent(interface{}, interface{}) bool
|
||||
|
||||
// SameRules returns true if the instance is equivalent to another Rules
|
||||
// instance.
|
||||
SameRules(Rules) bool
|
||||
}
|
||||
|
||||
// OrderedRules is an extension of Rules that can apply a partial order to
|
||||
|
|
|
@ -41,7 +41,7 @@ func NewSetFromSlice(rules Rules, vals []interface{}) Set {
|
|||
}
|
||||
|
||||
func sameRules(s1 Set, s2 Set) bool {
|
||||
return s1.rules == s2.rules
|
||||
return s1.rules.SameRules(s2.rules)
|
||||
}
|
||||
|
||||
func mustHaveSameRules(s1 Set, s2 Set) {
|
||||
|
@ -53,7 +53,7 @@ func mustHaveSameRules(s1 Set, s2 Set) {
|
|||
// HasRules returns true if and only if the receiving set has the given rules
|
||||
// instance as its rules.
|
||||
func (s Set) HasRules(rules Rules) bool {
|
||||
return s.rules == rules
|
||||
return s.rules.SameRules(rules)
|
||||
}
|
||||
|
||||
// Rules returns the receiving set's rules instance.
|
||||
|
|
|
@ -65,6 +65,17 @@ func (r setRules) Equivalent(v1 interface{}, v2 interface{}) bool {
|
|||
return eqv.v == true
|
||||
}
|
||||
|
||||
// SameRules is only true if the other Rules instance is also a setRules struct,
|
||||
// and the types are considered equal.
|
||||
func (r setRules) SameRules(other set.Rules) bool {
|
||||
rules, ok := other.(setRules)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return r.Type.Equals(rules.Type)
|
||||
}
|
||||
|
||||
// Less is an implementation of set.OrderedRules so that we can iterate over
|
||||
// set elements in a consistent order, where such an order is possible.
|
||||
func (r setRules) Less(v1, v2 interface{}) bool {
|
||||
|
|
|
@ -582,7 +582,7 @@ github.com/xanzy/ssh-agent
|
|||
# github.com/xlab/treeprint v0.0.0-20161029104018-1d6e34225557
|
||||
## explicit
|
||||
github.com/xlab/treeprint
|
||||
# github.com/zclconf/go-cty v1.4.0
|
||||
# github.com/zclconf/go-cty v1.4.1
|
||||
## explicit
|
||||
github.com/zclconf/go-cty/cty
|
||||
github.com/zclconf/go-cty/cty/convert
|
||||
|
|
Loading…
Reference in New Issue