terraform: ResourceConfig.IsComputed cases
This commit is contained in:
parent
0c271b2b2d
commit
29485f6167
|
@ -344,7 +344,7 @@ func TestConfigFieldReader_ComputedSet(t *testing.T) {
|
||||||
}, map[string]ast.Variable{
|
}, map[string]ast.Variable{
|
||||||
"var.foo": ast.Variable{
|
"var.foo": ast.Variable{
|
||||||
Value: config.UnknownVariableValue,
|
Value: config.UnknownVariableValue,
|
||||||
Type: ast.TypeString,
|
Type: ast.TypeUnknown,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
false,
|
false,
|
||||||
|
@ -362,7 +362,7 @@ func TestConfigFieldReader_ComputedSet(t *testing.T) {
|
||||||
}, map[string]ast.Variable{
|
}, map[string]ast.Variable{
|
||||||
"var.foo": ast.Variable{
|
"var.foo": ast.Variable{
|
||||||
Value: config.UnknownVariableValue,
|
Value: config.UnknownVariableValue,
|
||||||
Type: ast.TypeString,
|
Type: ast.TypeUnknown,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
false,
|
false,
|
||||||
|
|
|
@ -209,6 +209,15 @@ func (c *ResourceConfig) GetRaw(k string) (interface{}, bool) {
|
||||||
|
|
||||||
// IsComputed returns whether the given key is computed or not.
|
// IsComputed returns whether the given key is computed or not.
|
||||||
func (c *ResourceConfig) IsComputed(k string) bool {
|
func (c *ResourceConfig) IsComputed(k string) bool {
|
||||||
|
// First, check for pure computed key equality since that is fast
|
||||||
|
for _, ck := range c.ComputedKeys {
|
||||||
|
if ck == k {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The next thing we do is check the config if we get a computed
|
||||||
|
// value out of it.
|
||||||
v, ok := c.get(k, c.Config)
|
v, ok := c.get(k, c.Config)
|
||||||
_, okRaw := c.get(k, c.Raw)
|
_, okRaw := c.get(k, c.Raw)
|
||||||
|
|
||||||
|
@ -252,6 +261,7 @@ func (c *ResourceConfig) get(
|
||||||
var current interface{} = raw
|
var current interface{} = raw
|
||||||
var previous interface{} = nil
|
var previous interface{} = nil
|
||||||
for i, part := range parts {
|
for i, part := range parts {
|
||||||
|
println(fmt.Sprintf("%#v: %#v %T", part, current, current))
|
||||||
if current == nil {
|
if current == nil {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
@ -268,6 +278,7 @@ func (c *ResourceConfig) get(
|
||||||
if !v.IsValid() {
|
if !v.IsValid() {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
return v.Interface(), true
|
return v.Interface(), true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,22 +310,39 @@ func (c *ResourceConfig) get(
|
||||||
current = cv.Index(int(i)).Interface()
|
current = cv.Index(int(i)).Interface()
|
||||||
}
|
}
|
||||||
case reflect.String:
|
case reflect.String:
|
||||||
|
// If we get the unknown value, return that
|
||||||
|
if current == unknownValue() {
|
||||||
|
return current, false
|
||||||
|
}
|
||||||
|
|
||||||
// This happens when map keys contain "." and have a common
|
// This happens when map keys contain "." and have a common
|
||||||
// prefix so were split as path components above.
|
// prefix so were split as path components above.
|
||||||
actualKey := strings.Join(parts[i-1:], ".")
|
actualKey := strings.Join(parts[i-1:], ".")
|
||||||
if prevMap, ok := previous.(map[string]interface{}); ok {
|
if prevMap, ok := previous.(map[string]interface{}); ok {
|
||||||
return prevMap[actualKey], true
|
return prevMap[actualKey], true
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, false
|
return nil, false
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("Unknown kind: %s", cv.Kind()))
|
panic(fmt.Sprintf("Unknown kind: %s", cv.Kind()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the value is just the unknown value, then we don't
|
switch cv := reflect.ValueOf(current); cv.Kind() {
|
||||||
// know anything beyond here.
|
case reflect.Slice:
|
||||||
if current == unknownValue() {
|
// If any value in a list is computed, this whole thing
|
||||||
return current, false
|
// is computed and we can't read any part of it.
|
||||||
|
for i := 0; i < cv.Len(); i++ {
|
||||||
|
if v := cv.Index(i).Interface(); v == unknownValue() {
|
||||||
|
return v, false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
// If the value is just the unknown value, then we don't
|
||||||
|
// know anything beyond here.
|
||||||
|
if current == unknownValue() {
|
||||||
|
return current, false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return current, true
|
return current, true
|
||||||
|
|
|
@ -326,6 +326,23 @@ func TestResourceConfigIsComputed(t *testing.T) {
|
||||||
Key: "foo.#",
|
Key: "foo.#",
|
||||||
Result: true,
|
Result: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
Name: "nested set with computed elements",
|
||||||
|
Config: map[string]interface{}{
|
||||||
|
"route": []map[string]interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"index": "1",
|
||||||
|
"gateway": []interface{}{"${var.foo}"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Vars: map[string]interface{}{
|
||||||
|
"foo": unknownValue(),
|
||||||
|
},
|
||||||
|
Key: "route.0.gateway",
|
||||||
|
Result: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, tc := range cases {
|
for i, tc := range cases {
|
||||||
|
|
Loading…
Reference in New Issue