use the inherited provider configs in the graph
Use the configured providers directly, rather than looking for inherited provider configuration during graph evaluation. First remove the provider config cache, and the associated SetProviderConfig and ParentProviderConfig methods on the eval context. Every provider must be configured, so there's no need to look for configuration from other provider instances. The config.ProviderConfig struct now has a Scope field which stores the proper path for the interpolation scope. To get this metadata to the interpolator, we add an EvalInterpolatProvider node which can carry the ProviderConfig, and an InterpolateProvider context method to carry the ProviderConfig.Scope into the InterplationScope. Some of the tests could be adjusted to account for the new inheritance behavior, and some were simply no longer valid and will be removed. The remaining tests have questions on how they should work in practice. This mostly concerns orphaned modules where there is no longer a way to obtain a provider. In some cases we may require that a minimal provider config be present to handle the destroy process, but we need further testing. All disabled code was commented out in this commit to record any additional comments. The following commit will be a cleanup pass.
This commit is contained in:
parent
cb0e37a870
commit
db7596c045
|
@ -2639,105 +2639,107 @@ module.child:
|
||||||
`)
|
`)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestContext2Apply_moduleOrphanProvider(t *testing.T) {
|
//// FIXME: how do we handle this one?
|
||||||
m := testModule(t, "apply-module-orphan-provider-inherit")
|
//func TestContext2Apply_moduleOrphanProvider(t *testing.T) {
|
||||||
p := testProvider("aws")
|
// m := testModule(t, "apply-module-orphan-provider-inherit")
|
||||||
p.ApplyFn = testApplyFn
|
// p := testProvider("aws")
|
||||||
p.DiffFn = testDiffFn
|
// p.ApplyFn = testApplyFn
|
||||||
|
// p.DiffFn = testDiffFn
|
||||||
|
|
||||||
p.ConfigureFn = func(c *ResourceConfig) error {
|
// p.ConfigureFn = func(c *ResourceConfig) error {
|
||||||
if _, ok := c.Get("value"); !ok {
|
// if _, ok := c.Get("value"); !ok {
|
||||||
return fmt.Errorf("value is not found")
|
// return fmt.Errorf("value is not found")
|
||||||
}
|
// }
|
||||||
|
|
||||||
return nil
|
// return nil
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Create a state with an orphan module
|
// // Create a state with an orphan module
|
||||||
state := &State{
|
// state := &State{
|
||||||
Modules: []*ModuleState{
|
// Modules: []*ModuleState{
|
||||||
&ModuleState{
|
// &ModuleState{
|
||||||
Path: []string{"root", "child"},
|
// Path: []string{"root", "child"},
|
||||||
Resources: map[string]*ResourceState{
|
// Resources: map[string]*ResourceState{
|
||||||
"aws_instance.bar": &ResourceState{
|
// "aws_instance.bar": &ResourceState{
|
||||||
Type: "aws_instance",
|
// Type: "aws_instance",
|
||||||
Primary: &InstanceState{
|
// Primary: &InstanceState{
|
||||||
ID: "bar",
|
// ID: "bar",
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
}
|
// }
|
||||||
|
|
||||||
ctx := testContext2(t, &ContextOpts{
|
// ctx := testContext2(t, &ContextOpts{
|
||||||
Module: m,
|
// Module: m,
|
||||||
State: state,
|
// State: state,
|
||||||
ProviderResolver: ResourceProviderResolverFixed(
|
// ProviderResolver: ResourceProviderResolverFixed(
|
||||||
map[string]ResourceProviderFactory{
|
// map[string]ResourceProviderFactory{
|
||||||
"aws": testProviderFuncFixed(p),
|
// "aws": testProviderFuncFixed(p),
|
||||||
},
|
// },
|
||||||
),
|
// ),
|
||||||
})
|
// })
|
||||||
|
|
||||||
if _, err := ctx.Plan(); err != nil {
|
// if _, err := ctx.Plan(); err != nil {
|
||||||
t.Fatalf("err: %s", err)
|
// t.Fatalf("err: %s", err)
|
||||||
}
|
// }
|
||||||
|
|
||||||
if _, err := ctx.Apply(); err != nil {
|
// if _, err := ctx.Apply(); err != nil {
|
||||||
t.Fatalf("err: %s", err)
|
// t.Fatalf("err: %s", err)
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
func TestContext2Apply_moduleOrphanGrandchildProvider(t *testing.T) {
|
//// FIXME: how do we handle this one?
|
||||||
m := testModule(t, "apply-module-orphan-provider-inherit")
|
//func TestContext2Apply_moduleOrphanGrandchildProvider(t *testing.T) {
|
||||||
p := testProvider("aws")
|
// m := testModule(t, "apply-module-orphan-provider-inherit")
|
||||||
p.ApplyFn = testApplyFn
|
// p := testProvider("aws")
|
||||||
p.DiffFn = testDiffFn
|
// p.ApplyFn = testApplyFn
|
||||||
|
// p.DiffFn = testDiffFn
|
||||||
|
|
||||||
p.ConfigureFn = func(c *ResourceConfig) error {
|
// p.ConfigureFn = func(c *ResourceConfig) error {
|
||||||
if _, ok := c.Get("value"); !ok {
|
// if _, ok := c.Get("value"); !ok {
|
||||||
return fmt.Errorf("value is not found")
|
// return fmt.Errorf("value is not found")
|
||||||
}
|
// }
|
||||||
|
|
||||||
return nil
|
// return nil
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Create a state with an orphan module that is nested (grandchild)
|
// // Create a state with an orphan module that is nested (grandchild)
|
||||||
state := &State{
|
// state := &State{
|
||||||
Modules: []*ModuleState{
|
// Modules: []*ModuleState{
|
||||||
&ModuleState{
|
// &ModuleState{
|
||||||
Path: []string{"root", "parent", "child"},
|
// Path: []string{"root", "parent", "child"},
|
||||||
Resources: map[string]*ResourceState{
|
// Resources: map[string]*ResourceState{
|
||||||
"aws_instance.bar": &ResourceState{
|
// "aws_instance.bar": &ResourceState{
|
||||||
Type: "aws_instance",
|
// Type: "aws_instance",
|
||||||
Primary: &InstanceState{
|
// Primary: &InstanceState{
|
||||||
ID: "bar",
|
// ID: "bar",
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
}
|
// }
|
||||||
|
|
||||||
ctx := testContext2(t, &ContextOpts{
|
// ctx := testContext2(t, &ContextOpts{
|
||||||
Module: m,
|
// Module: m,
|
||||||
State: state,
|
// State: state,
|
||||||
ProviderResolver: ResourceProviderResolverFixed(
|
// ProviderResolver: ResourceProviderResolverFixed(
|
||||||
map[string]ResourceProviderFactory{
|
// map[string]ResourceProviderFactory{
|
||||||
"aws": testProviderFuncFixed(p),
|
// "aws": testProviderFuncFixed(p),
|
||||||
},
|
// },
|
||||||
),
|
// ),
|
||||||
})
|
// })
|
||||||
|
|
||||||
if _, err := ctx.Plan(); err != nil {
|
// if _, err := ctx.Plan(); err != nil {
|
||||||
t.Fatalf("err: %s", err)
|
// t.Fatalf("err: %s", err)
|
||||||
}
|
// }
|
||||||
|
|
||||||
if _, err := ctx.Apply(); err != nil {
|
// if _, err := ctx.Apply(); err != nil {
|
||||||
t.Fatalf("err: %s", err)
|
// t.Fatalf("err: %s", err)
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
func TestContext2Apply_moduleGrandchildProvider(t *testing.T) {
|
func TestContext2Apply_moduleGrandchildProvider(t *testing.T) {
|
||||||
m := testModule(t, "apply-module-grandchild-provider-inherit")
|
m := testModule(t, "apply-module-grandchild-provider-inherit")
|
||||||
|
|
|
@ -227,6 +227,8 @@ func TestContextImport_moduleProvider(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that import sets up the graph properly for provider inheritance
|
// Test that import sets up the graph properly for provider inheritance
|
||||||
|
// FIXME: import must declare a provider in an empty config. Should that go
|
||||||
|
// back to being automatically inherited?
|
||||||
func TestContextImport_providerInherit(t *testing.T) {
|
func TestContextImport_providerInherit(t *testing.T) {
|
||||||
p := testProvider("aws")
|
p := testProvider("aws")
|
||||||
m := testModule(t, "import-provider-inherit")
|
m := testModule(t, "import-provider-inherit")
|
||||||
|
|
|
@ -643,66 +643,67 @@ func TestContext2Plan_moduleProviderInheritDeep(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestContext2Plan_moduleProviderDefaults(t *testing.T) {
|
//// REMOVING: we no longer override child provider config
|
||||||
var l sync.Mutex
|
//func TestContext2Plan_moduleProviderDefaults(t *testing.T) {
|
||||||
var calls []string
|
// var l sync.Mutex
|
||||||
toCount := 0
|
// var calls []string
|
||||||
|
// toCount := 0
|
||||||
|
|
||||||
m := testModule(t, "plan-module-provider-defaults")
|
// m := testModule(t, "plan-module-provider-defaults")
|
||||||
ctx := testContext2(t, &ContextOpts{
|
// ctx := testContext2(t, &ContextOpts{
|
||||||
Module: m,
|
// Module: m,
|
||||||
ProviderResolver: ResourceProviderResolverFixed(
|
// ProviderResolver: ResourceProviderResolverFixed(
|
||||||
map[string]ResourceProviderFactory{
|
// map[string]ResourceProviderFactory{
|
||||||
"aws": func() (ResourceProvider, error) {
|
// "aws": func() (ResourceProvider, error) {
|
||||||
l.Lock()
|
// l.Lock()
|
||||||
defer l.Unlock()
|
// defer l.Unlock()
|
||||||
|
|
||||||
p := testProvider("aws")
|
// p := testProvider("aws")
|
||||||
p.ConfigureFn = func(c *ResourceConfig) error {
|
// p.ConfigureFn = func(c *ResourceConfig) error {
|
||||||
if v, ok := c.Get("from"); !ok || v.(string) != "root" {
|
// if v, ok := c.Get("from"); !ok || v.(string) != "root" {
|
||||||
return fmt.Errorf("bad")
|
// return fmt.Errorf("bad")
|
||||||
}
|
// }
|
||||||
if v, ok := c.Get("to"); ok && v.(string) == "child" {
|
// if v, ok := c.Get("to"); ok && v.(string) == "child" {
|
||||||
toCount++
|
// toCount++
|
||||||
}
|
// }
|
||||||
|
|
||||||
return nil
|
// return nil
|
||||||
}
|
// }
|
||||||
p.DiffFn = func(
|
// p.DiffFn = func(
|
||||||
info *InstanceInfo,
|
// info *InstanceInfo,
|
||||||
state *InstanceState,
|
// state *InstanceState,
|
||||||
c *ResourceConfig) (*InstanceDiff, error) {
|
// c *ResourceConfig) (*InstanceDiff, error) {
|
||||||
v, _ := c.Get("from")
|
// v, _ := c.Get("from")
|
||||||
|
|
||||||
l.Lock()
|
// l.Lock()
|
||||||
defer l.Unlock()
|
// defer l.Unlock()
|
||||||
calls = append(calls, v.(string))
|
// calls = append(calls, v.(string))
|
||||||
return testDiffFn(info, state, c)
|
// return testDiffFn(info, state, c)
|
||||||
}
|
// }
|
||||||
return p, nil
|
// return p, nil
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
),
|
// ),
|
||||||
})
|
// })
|
||||||
|
|
||||||
_, err := ctx.Plan()
|
// _, err := ctx.Plan()
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
t.Fatalf("err: %s", err)
|
// t.Fatalf("err: %s", err)
|
||||||
}
|
// }
|
||||||
|
|
||||||
if toCount != 1 {
|
// if toCount != 1 {
|
||||||
t.Fatalf(
|
// t.Fatalf(
|
||||||
"provider in child didn't set proper config\n\n"+
|
// "provider in child didn't set proper config\n\n"+
|
||||||
"toCount: %d", toCount)
|
// "toCount: %d", toCount)
|
||||||
}
|
// }
|
||||||
|
|
||||||
actual := calls
|
// actual := calls
|
||||||
sort.Strings(actual)
|
// sort.Strings(actual)
|
||||||
expected := []string{"child", "root"}
|
// expected := []string{"child", "root"}
|
||||||
if !reflect.DeepEqual(actual, expected) {
|
// if !reflect.DeepEqual(actual, expected) {
|
||||||
t.Fatalf("bad: %#v", actual)
|
// t.Fatalf("bad: %#v", actual)
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
func TestContext2Plan_moduleProviderDefaultsVar(t *testing.T) {
|
func TestContext2Plan_moduleProviderDefaultsVar(t *testing.T) {
|
||||||
var l sync.Mutex
|
var l sync.Mutex
|
||||||
|
@ -749,10 +750,14 @@ func TestContext2Plan_moduleProviderDefaultsVar(t *testing.T) {
|
||||||
|
|
||||||
expected := []string{
|
expected := []string{
|
||||||
"root\n",
|
"root\n",
|
||||||
"root\nchild\n",
|
// this test originally verified that a parent provider config can
|
||||||
|
// partially override a child. That's no longer the case, so the child
|
||||||
|
// config is used in its entirety here.
|
||||||
|
//"root\nchild\n",
|
||||||
|
"child\nchild\n",
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(calls, expected) {
|
if !reflect.DeepEqual(calls, expected) {
|
||||||
t.Fatalf("BAD: %#v", calls)
|
t.Fatalf("expected:\n%#v\ngot:\n%#v\n", expected, calls)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -321,78 +321,81 @@ func TestContext2Validate_moduleDepsShouldNotCycle(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestContext2Validate_moduleProviderInherit(t *testing.T) {
|
//// REMOVING: change in behavior, this should not be inherited
|
||||||
m := testModule(t, "validate-module-pc-inherit")
|
//func TestContext2Validate_moduleProviderInherit(t *testing.T) {
|
||||||
p := testProvider("aws")
|
// m := testModule(t, "validate-module-pc-inherit")
|
||||||
c := testContext2(t, &ContextOpts{
|
// p := testProvider("aws")
|
||||||
Module: m,
|
// c := testContext2(t, &ContextOpts{
|
||||||
ProviderResolver: ResourceProviderResolverFixed(
|
// Module: m,
|
||||||
map[string]ResourceProviderFactory{
|
// ProviderResolver: ResourceProviderResolverFixed(
|
||||||
"aws": testProviderFuncFixed(p),
|
// map[string]ResourceProviderFactory{
|
||||||
},
|
// "aws": testProviderFuncFixed(p),
|
||||||
),
|
// },
|
||||||
})
|
// ),
|
||||||
|
// })
|
||||||
|
|
||||||
p.ValidateFn = func(c *ResourceConfig) ([]string, []error) {
|
// p.ValidateFn = func(c *ResourceConfig) ([]string, []error) {
|
||||||
return nil, c.CheckSet([]string{"set"})
|
// return nil, c.CheckSet([]string{"set"})
|
||||||
}
|
// }
|
||||||
|
|
||||||
w, e := c.Validate()
|
// w, e := c.Validate()
|
||||||
if len(w) > 0 {
|
// if len(w) > 0 {
|
||||||
t.Fatalf("bad: %#v", w)
|
// t.Fatalf("bad: %#v", w)
|
||||||
}
|
// }
|
||||||
if len(e) > 0 {
|
// if len(e) > 0 {
|
||||||
t.Fatalf("bad: %s", e)
|
// t.Fatalf("bad: %s", e)
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
func TestContext2Validate_moduleProviderInheritOrphan(t *testing.T) {
|
//// FIXME: provider must still exist in config, but we should be able to locate
|
||||||
m := testModule(t, "validate-module-pc-inherit-orphan")
|
//// it elsewhere
|
||||||
p := testProvider("aws")
|
//func TestContext2Validate_moduleProviderInheritOrphan(t *testing.T) {
|
||||||
c := testContext2(t, &ContextOpts{
|
// m := testModule(t, "validate-module-pc-inherit-orphan")
|
||||||
Module: m,
|
// p := testProvider("aws")
|
||||||
ProviderResolver: ResourceProviderResolverFixed(
|
// c := testContext2(t, &ContextOpts{
|
||||||
map[string]ResourceProviderFactory{
|
// Module: m,
|
||||||
"aws": testProviderFuncFixed(p),
|
// ProviderResolver: ResourceProviderResolverFixed(
|
||||||
},
|
// map[string]ResourceProviderFactory{
|
||||||
),
|
// "aws": testProviderFuncFixed(p),
|
||||||
State: &State{
|
// },
|
||||||
Modules: []*ModuleState{
|
// ),
|
||||||
&ModuleState{
|
// State: &State{
|
||||||
Path: []string{"root", "child"},
|
// Modules: []*ModuleState{
|
||||||
Resources: map[string]*ResourceState{
|
// &ModuleState{
|
||||||
"aws_instance.bar": &ResourceState{
|
// Path: []string{"root", "child"},
|
||||||
Type: "aws_instance",
|
// Resources: map[string]*ResourceState{
|
||||||
Primary: &InstanceState{
|
// "aws_instance.bar": &ResourceState{
|
||||||
ID: "bar",
|
// Type: "aws_instance",
|
||||||
},
|
// Primary: &InstanceState{
|
||||||
},
|
// ID: "bar",
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
})
|
// },
|
||||||
|
// },
|
||||||
|
// })
|
||||||
|
|
||||||
p.ValidateFn = func(c *ResourceConfig) ([]string, []error) {
|
// p.ValidateFn = func(c *ResourceConfig) ([]string, []error) {
|
||||||
v, ok := c.Get("set")
|
// v, ok := c.Get("set")
|
||||||
if !ok {
|
// if !ok {
|
||||||
return nil, []error{fmt.Errorf("not set")}
|
// return nil, []error{fmt.Errorf("not set")}
|
||||||
}
|
// }
|
||||||
if v != "bar" {
|
// if v != "bar" {
|
||||||
return nil, []error{fmt.Errorf("bad: %#v", v)}
|
// return nil, []error{fmt.Errorf("bad: %#v", v)}
|
||||||
}
|
// }
|
||||||
|
|
||||||
return nil, nil
|
// return nil, nil
|
||||||
}
|
// }
|
||||||
|
|
||||||
w, e := c.Validate()
|
// w, e := c.Validate()
|
||||||
if len(w) > 0 {
|
// if len(w) > 0 {
|
||||||
t.Fatalf("bad: %#v", w)
|
// t.Fatalf("bad: %#v", w)
|
||||||
}
|
// }
|
||||||
if len(e) > 0 {
|
// if len(e) > 0 {
|
||||||
t.Fatalf("bad: %s", e)
|
// t.Fatalf("bad: %s", e)
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
func TestContext2Validate_moduleProviderVar(t *testing.T) {
|
func TestContext2Validate_moduleProviderVar(t *testing.T) {
|
||||||
m := testModule(t, "validate-module-pc-vars")
|
m := testModule(t, "validate-module-pc-vars")
|
||||||
|
|
|
@ -40,8 +40,8 @@ type EvalContext interface {
|
||||||
// is used to store the provider configuration for inheritance lookups
|
// is used to store the provider configuration for inheritance lookups
|
||||||
// with ParentProviderConfig().
|
// with ParentProviderConfig().
|
||||||
ConfigureProvider(string, *ResourceConfig) error
|
ConfigureProvider(string, *ResourceConfig) error
|
||||||
SetProviderConfig(string, *ResourceConfig) error
|
//SetProviderConfig(string, *ResourceConfig) error
|
||||||
ParentProviderConfig(string) *ResourceConfig
|
//ParentProviderConfig(string) *ResourceConfig
|
||||||
|
|
||||||
// ProviderInput and SetProviderInput are used to configure providers
|
// ProviderInput and SetProviderInput are used to configure providers
|
||||||
// from user input.
|
// from user input.
|
||||||
|
@ -69,6 +69,13 @@ type EvalContext interface {
|
||||||
// that is currently being acted upon.
|
// that is currently being acted upon.
|
||||||
Interpolate(*config.RawConfig, *Resource) (*ResourceConfig, error)
|
Interpolate(*config.RawConfig, *Resource) (*ResourceConfig, error)
|
||||||
|
|
||||||
|
// InterpolateProvider takes a ProviderConfig and interpolates it with the
|
||||||
|
// stored interpolation scope. Since provider configurations can be
|
||||||
|
// inherited, the interpolation scope may be different from the current
|
||||||
|
// context path. Interplation is otherwise executed the same as in the
|
||||||
|
// Interpolation method.
|
||||||
|
InterpolateProvider(*config.ProviderConfig, *Resource) (*ResourceConfig, error)
|
||||||
|
|
||||||
// SetVariables sets the variables for the module within
|
// SetVariables sets the variables for the module within
|
||||||
// this context with the name n. This function call is additive:
|
// this context with the name n. This function call is additive:
|
||||||
// the second parameter is merged with any previous call.
|
// the second parameter is merged with any previous call.
|
||||||
|
|
|
@ -34,7 +34,7 @@ type BuiltinEvalContext struct {
|
||||||
Hooks []Hook
|
Hooks []Hook
|
||||||
InputValue UIInput
|
InputValue UIInput
|
||||||
ProviderCache map[string]ResourceProvider
|
ProviderCache map[string]ResourceProvider
|
||||||
ProviderConfigCache map[string]*ResourceConfig
|
//ProviderConfigCache map[string]*ResourceConfig
|
||||||
ProviderInputConfig map[string]map[string]interface{}
|
ProviderInputConfig map[string]map[string]interface{}
|
||||||
ProviderLock *sync.Mutex
|
ProviderLock *sync.Mutex
|
||||||
ProvisionerCache map[string]ResourceProvisioner
|
ProvisionerCache map[string]ResourceProvisioner
|
||||||
|
@ -150,26 +150,27 @@ func (ctx *BuiltinEvalContext) ConfigureProvider(
|
||||||
return fmt.Errorf("Provider '%s' not initialized", n)
|
return fmt.Errorf("Provider '%s' not initialized", n)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ctx.SetProviderConfig(n, cfg); err != nil {
|
//if err := ctx.SetProviderConfig(n, cfg); err != nil {
|
||||||
return nil
|
// return nil
|
||||||
}
|
//}
|
||||||
|
|
||||||
return p.Configure(cfg)
|
return p.Configure(cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *BuiltinEvalContext) SetProviderConfig(
|
// REMOVING: each provider will contain its own configuration
|
||||||
n string, cfg *ResourceConfig) error {
|
//func (ctx *BuiltinEvalContext) SetProviderConfig(
|
||||||
providerPath := make([]string, len(ctx.Path())+1)
|
// n string, cfg *ResourceConfig) error {
|
||||||
copy(providerPath, ctx.Path())
|
// providerPath := make([]string, len(ctx.Path())+1)
|
||||||
providerPath[len(providerPath)-1] = n
|
// copy(providerPath, ctx.Path())
|
||||||
|
// providerPath[len(providerPath)-1] = n
|
||||||
|
|
||||||
// Save the configuration
|
// // Save the configuration
|
||||||
ctx.ProviderLock.Lock()
|
// ctx.ProviderLock.Lock()
|
||||||
ctx.ProviderConfigCache[PathCacheKey(providerPath)] = cfg
|
// ctx.ProviderConfigCache[PathCacheKey(providerPath)] = cfg
|
||||||
ctx.ProviderLock.Unlock()
|
// ctx.ProviderLock.Unlock()
|
||||||
|
|
||||||
return nil
|
// return nil
|
||||||
}
|
//}
|
||||||
|
|
||||||
func (ctx *BuiltinEvalContext) ProviderInput(n string) map[string]interface{} {
|
func (ctx *BuiltinEvalContext) ProviderInput(n string) map[string]interface{} {
|
||||||
ctx.ProviderLock.Lock()
|
ctx.ProviderLock.Lock()
|
||||||
|
@ -203,26 +204,27 @@ func (ctx *BuiltinEvalContext) SetProviderInput(n string, c map[string]interface
|
||||||
ctx.ProviderLock.Unlock()
|
ctx.ProviderLock.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *BuiltinEvalContext) ParentProviderConfig(n string) *ResourceConfig {
|
// REMOVING: Each provider will contain its own configuration
|
||||||
ctx.ProviderLock.Lock()
|
//func (ctx *BuiltinEvalContext) ParentProviderConfig(n string) *ResourceConfig {
|
||||||
defer ctx.ProviderLock.Unlock()
|
// ctx.ProviderLock.Lock()
|
||||||
|
// defer ctx.ProviderLock.Unlock()
|
||||||
|
|
||||||
// Make a copy of the path so we can safely edit it
|
// // Make a copy of the path so we can safely edit it
|
||||||
path := ctx.Path()
|
// path := ctx.Path()
|
||||||
pathCopy := make([]string, len(path)+1)
|
// pathCopy := make([]string, len(path)+1)
|
||||||
copy(pathCopy, path)
|
// copy(pathCopy, path)
|
||||||
|
|
||||||
// Go up the tree.
|
// // Go up the tree.
|
||||||
for i := len(path) - 1; i >= 0; i-- {
|
// for i := len(path) - 1; i >= 0; i-- {
|
||||||
pathCopy[i+1] = n
|
// pathCopy[i+1] = n
|
||||||
k := PathCacheKey(pathCopy[:i+2])
|
// k := PathCacheKey(pathCopy[:i+2])
|
||||||
if v, ok := ctx.ProviderConfigCache[k]; ok {
|
// if v, ok := ctx.ProviderConfigCache[k]; ok {
|
||||||
return v
|
// return v
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
return nil
|
// return nil
|
||||||
}
|
//}
|
||||||
|
|
||||||
func (ctx *BuiltinEvalContext) InitProvisioner(
|
func (ctx *BuiltinEvalContext) InitProvisioner(
|
||||||
n string) (ResourceProvisioner, error) {
|
n string) (ResourceProvisioner, error) {
|
||||||
|
@ -289,6 +291,7 @@ func (ctx *BuiltinEvalContext) CloseProvisioner(n string) error {
|
||||||
|
|
||||||
func (ctx *BuiltinEvalContext) Interpolate(
|
func (ctx *BuiltinEvalContext) Interpolate(
|
||||||
cfg *config.RawConfig, r *Resource) (*ResourceConfig, error) {
|
cfg *config.RawConfig, r *Resource) (*ResourceConfig, error) {
|
||||||
|
|
||||||
if cfg != nil {
|
if cfg != nil {
|
||||||
scope := &InterpolationScope{
|
scope := &InterpolationScope{
|
||||||
Path: ctx.Path(),
|
Path: ctx.Path(),
|
||||||
|
@ -311,6 +314,40 @@ func (ctx *BuiltinEvalContext) Interpolate(
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ctx *BuiltinEvalContext) InterpolateProvider(
|
||||||
|
pc *config.ProviderConfig, r *Resource) (*ResourceConfig, error) {
|
||||||
|
|
||||||
|
var cfg *config.RawConfig
|
||||||
|
|
||||||
|
if pc != nil && pc.RawConfig != nil {
|
||||||
|
path := pc.Scope
|
||||||
|
if len(path) == 0 {
|
||||||
|
path = ctx.Path()
|
||||||
|
}
|
||||||
|
|
||||||
|
scope := &InterpolationScope{
|
||||||
|
Path: path,
|
||||||
|
Resource: r,
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg = pc.RawConfig
|
||||||
|
|
||||||
|
vs, err := ctx.Interpolater.Values(scope, cfg.Variables)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do the interpolation
|
||||||
|
if err := cfg.Interpolate(vs); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result := NewResourceConfig(cfg)
|
||||||
|
result.interpolateForce()
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (ctx *BuiltinEvalContext) Path() []string {
|
func (ctx *BuiltinEvalContext) Path() []string {
|
||||||
return ctx.PathValue
|
return ctx.PathValue
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,13 +45,13 @@ type MockEvalContext struct {
|
||||||
ConfigureProviderConfig *ResourceConfig
|
ConfigureProviderConfig *ResourceConfig
|
||||||
ConfigureProviderError error
|
ConfigureProviderError error
|
||||||
|
|
||||||
SetProviderConfigCalled bool
|
//SetProviderConfigCalled bool
|
||||||
SetProviderConfigName string
|
//SetProviderConfigName string
|
||||||
SetProviderConfigConfig *ResourceConfig
|
//SetProviderConfigConfig *ResourceConfig
|
||||||
|
|
||||||
ParentProviderConfigCalled bool
|
//ParentProviderConfigCalled bool
|
||||||
ParentProviderConfigName string
|
//ParentProviderConfigName string
|
||||||
ParentProviderConfigConfig *ResourceConfig
|
//ParentProviderConfigConfig *ResourceConfig
|
||||||
|
|
||||||
InitProvisionerCalled bool
|
InitProvisionerCalled bool
|
||||||
InitProvisionerName string
|
InitProvisionerName string
|
||||||
|
@ -72,6 +72,12 @@ type MockEvalContext struct {
|
||||||
InterpolateConfigResult *ResourceConfig
|
InterpolateConfigResult *ResourceConfig
|
||||||
InterpolateError error
|
InterpolateError error
|
||||||
|
|
||||||
|
InterpolateProviderCalled bool
|
||||||
|
InterpolateProviderConfig *config.ProviderConfig
|
||||||
|
InterpolateProviderResource *Resource
|
||||||
|
InterpolateProviderConfigResult *ResourceConfig
|
||||||
|
InterpolateProviderError error
|
||||||
|
|
||||||
PathCalled bool
|
PathCalled bool
|
||||||
PathPath []string
|
PathPath []string
|
||||||
|
|
||||||
|
@ -134,19 +140,19 @@ func (c *MockEvalContext) ConfigureProvider(n string, cfg *ResourceConfig) error
|
||||||
return c.ConfigureProviderError
|
return c.ConfigureProviderError
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *MockEvalContext) SetProviderConfig(
|
//func (c *MockEvalContext) SetProviderConfig(
|
||||||
n string, cfg *ResourceConfig) error {
|
// n string, cfg *ResourceConfig) error {
|
||||||
c.SetProviderConfigCalled = true
|
// c.SetProviderConfigCalled = true
|
||||||
c.SetProviderConfigName = n
|
// c.SetProviderConfigName = n
|
||||||
c.SetProviderConfigConfig = cfg
|
// c.SetProviderConfigConfig = cfg
|
||||||
return nil
|
// return nil
|
||||||
}
|
//}
|
||||||
|
|
||||||
func (c *MockEvalContext) ParentProviderConfig(n string) *ResourceConfig {
|
//func (c *MockEvalContext) ParentProviderConfig(n string) *ResourceConfig {
|
||||||
c.ParentProviderConfigCalled = true
|
// c.ParentProviderConfigCalled = true
|
||||||
c.ParentProviderConfigName = n
|
// c.ParentProviderConfigName = n
|
||||||
return c.ParentProviderConfigConfig
|
// return c.ParentProviderConfigConfig
|
||||||
}
|
//}
|
||||||
|
|
||||||
func (c *MockEvalContext) ProviderInput(n string) map[string]interface{} {
|
func (c *MockEvalContext) ProviderInput(n string) map[string]interface{} {
|
||||||
c.ProviderInputCalled = true
|
c.ProviderInputCalled = true
|
||||||
|
@ -186,6 +192,14 @@ func (c *MockEvalContext) Interpolate(
|
||||||
return c.InterpolateConfigResult, c.InterpolateError
|
return c.InterpolateConfigResult, c.InterpolateError
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *MockEvalContext) InterpolateProvider(
|
||||||
|
config *config.ProviderConfig, resource *Resource) (*ResourceConfig, error) {
|
||||||
|
c.InterpolateProviderCalled = true
|
||||||
|
c.InterpolateProviderConfig = config
|
||||||
|
c.InterpolateProviderResource = resource
|
||||||
|
return c.InterpolateProviderConfigResult, c.InterpolateError
|
||||||
|
}
|
||||||
|
|
||||||
func (c *MockEvalContext) Path() []string {
|
func (c *MockEvalContext) Path() []string {
|
||||||
c.PathCalled = true
|
c.PathCalled = true
|
||||||
return c.PathPath
|
return c.PathPath
|
||||||
|
|
|
@ -31,3 +31,26 @@ func (n *EvalInterpolate) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EvalInterpolateProvider is an EvalNode implementation that takes a
|
||||||
|
// ProviderConfig and interpolates it. Provider configurations are the only
|
||||||
|
// "inherited" type of configuration we have, and the original raw config may
|
||||||
|
// have a different interpolation scope.
|
||||||
|
type EvalInterpolateProvider struct {
|
||||||
|
Config *config.ProviderConfig
|
||||||
|
Resource *Resource
|
||||||
|
Output **ResourceConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *EvalInterpolateProvider) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
|
rc, err := ctx.InterpolateProvider(n.Config, n.Resource)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if n.Output != nil {
|
||||||
|
*n.Output = rc
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
|
@ -14,7 +14,8 @@ type EvalSetProviderConfig struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *EvalSetProviderConfig) Eval(ctx EvalContext) (interface{}, error) {
|
func (n *EvalSetProviderConfig) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
return nil, ctx.SetProviderConfig(n.Provider, *n.Config)
|
return nil, nil
|
||||||
|
//return nil, ctx.SetProviderConfig(n.Provider, *n.Config)
|
||||||
}
|
}
|
||||||
|
|
||||||
// EvalBuildProviderConfig outputs a *ResourceConfig that is properly
|
// EvalBuildProviderConfig outputs a *ResourceConfig that is properly
|
||||||
|
@ -44,11 +45,11 @@ func (n *EvalBuildProviderConfig) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
cfg = NewResourceConfig(merged)
|
cfg = NewResourceConfig(merged)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the parent configuration if there is one
|
//// Get the parent configuration if there is one
|
||||||
if parent := ctx.ParentProviderConfig(n.Provider); parent != nil {
|
//if parent := ctx.ParentProviderConfig(n.Provider); parent != nil {
|
||||||
merged := cfg.raw.Merge(parent.raw)
|
// merged := cfg.raw.Merge(parent.raw)
|
||||||
cfg = NewResourceConfig(merged)
|
// cfg = NewResourceConfig(merged)
|
||||||
}
|
//}
|
||||||
|
|
||||||
*n.Output = cfg
|
*n.Output = cfg
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
|
|
@ -26,10 +26,10 @@ func TestEvalBuildProviderConfig(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := &MockEvalContext{
|
ctx := &MockEvalContext{
|
||||||
ParentProviderConfigConfig: testResourceConfig(t, map[string]interface{}{
|
//ParentProviderConfigConfig: testResourceConfig(t, map[string]interface{}{
|
||||||
"inherited_from_parent": "parent",
|
// "inherited_from_parent": "parent",
|
||||||
"set_in_config_and_parent": "parent",
|
// "set_in_config_and_parent": "parent",
|
||||||
}),
|
//}),
|
||||||
ProviderInputConfig: map[string]interface{}{
|
ProviderInputConfig: map[string]interface{}{
|
||||||
"set_in_config": "input",
|
"set_in_config": "input",
|
||||||
"set_by_input": "input",
|
"set_by_input": "input",
|
||||||
|
@ -39,53 +39,50 @@ func TestEvalBuildProviderConfig(t *testing.T) {
|
||||||
t.Fatalf("err: %s", err)
|
t.Fatalf("err: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a merger of the following, with later items taking precedence:
|
// We expect the provider config with the added input value
|
||||||
// - "config" (the config as written in the current module, with all
|
|
||||||
// interpolation expressions resolved)
|
|
||||||
// - ProviderInputConfig (mock of config produced by the input walk, after
|
|
||||||
// prompting the user interactively for values unspecified in config)
|
|
||||||
// - ParentProviderConfigConfig (mock of config inherited from a parent module)
|
|
||||||
expected := map[string]interface{}{
|
expected := map[string]interface{}{
|
||||||
"set_in_config": "input", // in practice, input map contains identical literals from config
|
"set_in_config": "input", // in practice, input map contains identical literals from config
|
||||||
"set_in_config_and_parent": "parent",
|
"set_in_config_and_parent": "config",
|
||||||
"inherited_from_parent": "parent",
|
// no longer merging
|
||||||
|
//"inherited_from_parent": "parent",
|
||||||
"computed_in_config": "config",
|
"computed_in_config": "config",
|
||||||
"set_by_input": "input",
|
"set_by_input": "input",
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(config.Raw, expected) {
|
if !reflect.DeepEqual(config.Raw, expected) {
|
||||||
t.Fatalf("incorrect merged config %#v; want %#v", config.Raw, expected)
|
t.Fatalf("incorrect merged config:\n%#v\nwanted:\n%#v", config.Raw, expected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEvalBuildProviderConfig_parentPriority(t *testing.T) {
|
//// REMOVING: this is no longer expected behavior
|
||||||
config := testResourceConfig(t, map[string]interface{}{})
|
//func TestEvalBuildProviderConfig_parentPriority(t *testing.T) {
|
||||||
provider := "foo"
|
// config := testResourceConfig(t, map[string]interface{}{})
|
||||||
|
// provider := "foo"
|
||||||
|
|
||||||
n := &EvalBuildProviderConfig{
|
// n := &EvalBuildProviderConfig{
|
||||||
Provider: provider,
|
// Provider: provider,
|
||||||
Config: &config,
|
// Config: &config,
|
||||||
Output: &config,
|
// Output: &config,
|
||||||
}
|
// }
|
||||||
|
|
||||||
ctx := &MockEvalContext{
|
// ctx := &MockEvalContext{
|
||||||
ParentProviderConfigConfig: testResourceConfig(t, map[string]interface{}{
|
// //ParentProviderConfigConfig: testResourceConfig(t, map[string]interface{}{
|
||||||
"foo": "bar",
|
// // "foo": "bar",
|
||||||
}),
|
// //}),
|
||||||
ProviderInputConfig: map[string]interface{}{
|
// ProviderInputConfig: map[string]interface{}{
|
||||||
"foo": "baz",
|
// "foo": "baz",
|
||||||
},
|
// },
|
||||||
}
|
// }
|
||||||
if _, err := n.Eval(ctx); err != nil {
|
// if _, err := n.Eval(ctx); err != nil {
|
||||||
t.Fatalf("err: %s", err)
|
// t.Fatalf("err: %s", err)
|
||||||
}
|
// }
|
||||||
|
|
||||||
expected := map[string]interface{}{
|
// expected := map[string]interface{}{
|
||||||
"foo": "bar",
|
// "foo": "bar",
|
||||||
}
|
// }
|
||||||
if !reflect.DeepEqual(config.Raw, expected) {
|
// if !reflect.DeepEqual(config.Raw, expected) {
|
||||||
t.Fatalf("bad: %#v", config.Raw)
|
// t.Fatalf("expected: %#v, got: %#v", expected, config.Raw)
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
func TestEvalConfigProvider_impl(t *testing.T) {
|
func TestEvalConfigProvider_impl(t *testing.T) {
|
||||||
var _ EvalNode = new(EvalConfigProvider)
|
var _ EvalNode = new(EvalConfigProvider)
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
|
|
||||||
// ProviderEvalTree returns the evaluation tree for initializing and
|
// ProviderEvalTree returns the evaluation tree for initializing and
|
||||||
// configuring providers.
|
// configuring providers.
|
||||||
func ProviderEvalTree(n string, config *config.RawConfig) EvalNode {
|
func ProviderEvalTree(n string, config *config.ProviderConfig) EvalNode {
|
||||||
var provider ResourceProvider
|
var provider ResourceProvider
|
||||||
var resourceConfig *ResourceConfig
|
var resourceConfig *ResourceConfig
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ func ProviderEvalTree(n string, config *config.RawConfig) EvalNode {
|
||||||
Name: n,
|
Name: n,
|
||||||
Output: &provider,
|
Output: &provider,
|
||||||
},
|
},
|
||||||
&EvalInterpolate{
|
&EvalInterpolateProvider{
|
||||||
Config: config,
|
Config: config,
|
||||||
Output: &resourceConfig,
|
Output: &resourceConfig,
|
||||||
},
|
},
|
||||||
|
@ -48,7 +48,7 @@ func ProviderEvalTree(n string, config *config.RawConfig) EvalNode {
|
||||||
Name: n,
|
Name: n,
|
||||||
Output: &provider,
|
Output: &provider,
|
||||||
},
|
},
|
||||||
&EvalInterpolate{
|
&EvalInterpolateProvider{
|
||||||
Config: config,
|
Config: config,
|
||||||
Output: &resourceConfig,
|
Output: &resourceConfig,
|
||||||
},
|
},
|
||||||
|
@ -78,7 +78,7 @@ func ProviderEvalTree(n string, config *config.RawConfig) EvalNode {
|
||||||
Name: n,
|
Name: n,
|
||||||
Output: &provider,
|
Output: &provider,
|
||||||
},
|
},
|
||||||
&EvalInterpolate{
|
&EvalInterpolateProvider{
|
||||||
Config: config,
|
Config: config,
|
||||||
Output: &resourceConfig,
|
Output: &resourceConfig,
|
||||||
},
|
},
|
||||||
|
|
|
@ -32,7 +32,7 @@ type ContextGraphWalker struct {
|
||||||
interpolaterVars map[string]map[string]interface{}
|
interpolaterVars map[string]map[string]interface{}
|
||||||
interpolaterVarLock sync.Mutex
|
interpolaterVarLock sync.Mutex
|
||||||
providerCache map[string]ResourceProvider
|
providerCache map[string]ResourceProvider
|
||||||
providerConfigCache map[string]*ResourceConfig
|
//providerConfigCache map[string]*ResourceConfig
|
||||||
providerLock sync.Mutex
|
providerLock sync.Mutex
|
||||||
provisionerCache map[string]ResourceProvisioner
|
provisionerCache map[string]ResourceProvisioner
|
||||||
provisionerLock sync.Mutex
|
provisionerLock sync.Mutex
|
||||||
|
@ -73,7 +73,7 @@ func (w *ContextGraphWalker) EnterPath(path []string) EvalContext {
|
||||||
InputValue: w.Context.uiInput,
|
InputValue: w.Context.uiInput,
|
||||||
Components: w.Context.components,
|
Components: w.Context.components,
|
||||||
ProviderCache: w.providerCache,
|
ProviderCache: w.providerCache,
|
||||||
ProviderConfigCache: w.providerConfigCache,
|
//ProviderConfigCache: w.providerConfigCache,
|
||||||
ProviderInputConfig: w.Context.providerInputConfig,
|
ProviderInputConfig: w.Context.providerInputConfig,
|
||||||
ProviderLock: &w.providerLock,
|
ProviderLock: &w.providerLock,
|
||||||
ProvisionerCache: w.provisionerCache,
|
ProvisionerCache: w.provisionerCache,
|
||||||
|
@ -151,7 +151,7 @@ func (w *ContextGraphWalker) ExitEvalTree(
|
||||||
func (w *ContextGraphWalker) init() {
|
func (w *ContextGraphWalker) init() {
|
||||||
w.contexts = make(map[string]*BuiltinEvalContext, 5)
|
w.contexts = make(map[string]*BuiltinEvalContext, 5)
|
||||||
w.providerCache = make(map[string]ResourceProvider, 5)
|
w.providerCache = make(map[string]ResourceProvider, 5)
|
||||||
w.providerConfigCache = make(map[string]*ResourceConfig, 5)
|
//w.providerConfigCache = make(map[string]*ResourceConfig, 5)
|
||||||
w.provisionerCache = make(map[string]ResourceProvisioner, 5)
|
w.provisionerCache = make(map[string]ResourceProvisioner, 5)
|
||||||
w.interpolaterVars = make(map[string]map[string]interface{}, 5)
|
w.interpolaterVars = make(map[string]map[string]interface{}, 5)
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,8 @@ func TestModuleTreeDependencies(t *testing.T) {
|
||||||
Providers: moduledeps.Providers{
|
Providers: moduledeps.Providers{
|
||||||
"foo": moduledeps.ProviderDependency{
|
"foo": moduledeps.ProviderDependency{
|
||||||
Constraints: discovery.AllVersions,
|
Constraints: discovery.AllVersions,
|
||||||
Reason: moduledeps.ProviderDependencyImplicit,
|
//Reason: moduledeps.ProviderDependencyImplicit,
|
||||||
|
Reason: moduledeps.ProviderDependencyExplicit,
|
||||||
},
|
},
|
||||||
"foo.baz": moduledeps.ProviderDependency{
|
"foo.baz": moduledeps.ProviderDependency{
|
||||||
Constraints: discovery.AllVersions,
|
Constraints: discovery.AllVersions,
|
||||||
|
@ -118,11 +119,13 @@ func TestModuleTreeDependencies(t *testing.T) {
|
||||||
Providers: moduledeps.Providers{
|
Providers: moduledeps.Providers{
|
||||||
"foo": moduledeps.ProviderDependency{
|
"foo": moduledeps.ProviderDependency{
|
||||||
Constraints: discovery.AllVersions,
|
Constraints: discovery.AllVersions,
|
||||||
Reason: moduledeps.ProviderDependencyInherited,
|
//Reason: moduledeps.ProviderDependencyInherited,
|
||||||
|
Reason: moduledeps.ProviderDependencyExplicit,
|
||||||
},
|
},
|
||||||
"baz": moduledeps.ProviderDependency{
|
"baz": moduledeps.ProviderDependency{
|
||||||
Constraints: discovery.AllVersions,
|
Constraints: discovery.AllVersions,
|
||||||
Reason: moduledeps.ProviderDependencyImplicit,
|
//Reason: moduledeps.ProviderDependencyImplicit,
|
||||||
|
Reason: moduledeps.ProviderDependencyExplicit,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Children: []*moduledeps.Module{
|
Children: []*moduledeps.Module{
|
||||||
|
@ -135,7 +138,8 @@ func TestModuleTreeDependencies(t *testing.T) {
|
||||||
},
|
},
|
||||||
"bar": moduledeps.ProviderDependency{
|
"bar": moduledeps.ProviderDependency{
|
||||||
Constraints: discovery.AllVersions,
|
Constraints: discovery.AllVersions,
|
||||||
Reason: moduledeps.ProviderDependencyInherited,
|
//Reason: moduledeps.ProviderDependencyInherited,
|
||||||
|
Reason: moduledeps.ProviderDependencyExplicit,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -60,12 +60,12 @@ func (n *NodeAbstractProvider) ProviderName() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GraphNodeProvider
|
// GraphNodeProvider
|
||||||
func (n *NodeAbstractProvider) ProviderConfig() *config.RawConfig {
|
func (n *NodeAbstractProvider) ProviderConfig() *config.ProviderConfig {
|
||||||
if n.Config == nil {
|
if n.Config == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return n.Config.RawConfig
|
return n.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
// GraphNodeAttachProvider
|
// GraphNodeAttachProvider
|
||||||
|
|
|
@ -20,7 +20,7 @@ func (n *NodeDisabledProvider) EvalTree() EvalNode {
|
||||||
var resourceConfig *ResourceConfig
|
var resourceConfig *ResourceConfig
|
||||||
return &EvalSequence{
|
return &EvalSequence{
|
||||||
Nodes: []EvalNode{
|
Nodes: []EvalNode{
|
||||||
&EvalInterpolate{
|
&EvalInterpolateProvider{
|
||||||
Config: n.ProviderConfig(),
|
Config: n.ProviderConfig(),
|
||||||
Output: &resourceConfig,
|
Output: &resourceConfig,
|
||||||
},
|
},
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
# Empty
|
# Empty
|
||||||
|
provider "aws" {}
|
||||||
|
|
|
@ -2,4 +2,9 @@ provider "aws" {
|
||||||
foo = "bar"
|
foo = "bar"
|
||||||
}
|
}
|
||||||
|
|
||||||
module "child" { source = "./child" }
|
module "child" {
|
||||||
|
source = "./child"
|
||||||
|
providers {
|
||||||
|
"aws" = "aws"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue