terraform: provider input should be scoped by path
The provider input before wasn't scoped by path, which caused non-descendant parts of the graph to grab the configuration of another sub-tree. The result is that you'd often get copied provider configurations across the module barriers. See GH-2024
This commit is contained in:
parent
cddd54c3de
commit
d0519f226d
|
@ -168,14 +168,32 @@ func (ctx *BuiltinEvalContext) ProviderInput(n string) map[string]interface{} {
|
|||
ctx.ProviderLock.Lock()
|
||||
defer ctx.ProviderLock.Unlock()
|
||||
|
||||
return ctx.ProviderInputConfig[n]
|
||||
// Make a copy of the path so we can safely edit it
|
||||
path := ctx.Path()
|
||||
pathCopy := make([]string, len(path)+1)
|
||||
copy(pathCopy, path)
|
||||
|
||||
// Go up the tree.
|
||||
for i := len(path) - 1; i >= 0; i-- {
|
||||
pathCopy[i+1] = n
|
||||
k := PathCacheKey(pathCopy[:i+2])
|
||||
if v, ok := ctx.ProviderInputConfig[k]; ok {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ctx *BuiltinEvalContext) SetProviderInput(n string, c map[string]interface{}) {
|
||||
ctx.ProviderLock.Lock()
|
||||
defer ctx.ProviderLock.Unlock()
|
||||
providerPath := make([]string, len(ctx.Path())+1)
|
||||
copy(providerPath, ctx.Path())
|
||||
providerPath[len(providerPath)-1] = n
|
||||
|
||||
ctx.ProviderInputConfig[n] = c
|
||||
// Save the configuration
|
||||
ctx.ProviderLock.Lock()
|
||||
ctx.ProviderInputConfig[PathCacheKey(providerPath)] = c
|
||||
ctx.ProviderLock.Unlock()
|
||||
}
|
||||
|
||||
func (ctx *BuiltinEvalContext) ParentProviderConfig(n string) *ResourceConfig {
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
package terraform
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sync"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBuiltinEvalContextProviderInput(t *testing.T) {
|
||||
var lock sync.Mutex
|
||||
cache := make(map[string]map[string]interface{})
|
||||
|
||||
ctx1 := testBuiltinEvalContext(t)
|
||||
ctx1.PathValue = []string{"root"}
|
||||
ctx1.ProviderInputConfig = cache
|
||||
ctx1.ProviderLock = &lock
|
||||
|
||||
ctx2 := testBuiltinEvalContext(t)
|
||||
ctx2.PathValue = []string{"root", "child"}
|
||||
ctx2.ProviderInputConfig = cache
|
||||
ctx2.ProviderLock = &lock
|
||||
|
||||
expected1 := map[string]interface{}{"value": "foo"}
|
||||
ctx1.SetProviderInput("foo", expected1)
|
||||
|
||||
expected2 := map[string]interface{}{"value": "bar"}
|
||||
ctx2.SetProviderInput("foo", expected2)
|
||||
|
||||
actual1 := ctx1.ProviderInput("foo")
|
||||
actual2 := ctx2.ProviderInput("foo")
|
||||
|
||||
if !reflect.DeepEqual(actual1, expected1) {
|
||||
t.Fatalf("bad: %#v %#v", actual1, expected1)
|
||||
}
|
||||
if !reflect.DeepEqual(actual2, expected2) {
|
||||
t.Fatalf("bad: %#v %#v", actual2, expected2)
|
||||
}
|
||||
}
|
||||
|
||||
func testBuiltinEvalContext(t *testing.T) *BuiltinEvalContext {
|
||||
return &BuiltinEvalContext{}
|
||||
}
|
Loading…
Reference in New Issue