remove provider inheritance from Tree.Load
Now that resources can be connected to providers with different paths in the core graph, handling the inheritance in config makes less sense. Removing this to make room for core to walk the Tree and connect resources directly to the proper provider instance.
This commit is contained in:
parent
57470f6bf5
commit
b15258dfec
|
@ -1,13 +0,0 @@
|
||||||
provider "top" {}
|
|
||||||
|
|
||||||
provider "bottom" {
|
|
||||||
alias = "foo"
|
|
||||||
value = "from bottom"
|
|
||||||
}
|
|
||||||
|
|
||||||
module "c" {
|
|
||||||
source = "../c"
|
|
||||||
providers = {
|
|
||||||
"bottom" = "bottom.foo"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,2 +0,0 @@
|
||||||
# Hello
|
|
||||||
provider "bottom" {}
|
|
|
@ -1,11 +0,0 @@
|
||||||
provider "top" {
|
|
||||||
alias = "foo"
|
|
||||||
value = "from top"
|
|
||||||
}
|
|
||||||
|
|
||||||
module "a" {
|
|
||||||
source = "./a"
|
|
||||||
providers = {
|
|
||||||
"top" = "top.foo"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -188,11 +188,6 @@ func (t *Tree) Load(s *Storage) error {
|
||||||
// Set our tree up
|
// Set our tree up
|
||||||
t.children = children
|
t.children = children
|
||||||
|
|
||||||
// if we're the root module, we can now set the provider inheritance
|
|
||||||
if len(t.path) == 0 {
|
|
||||||
t.inheritProviderConfigs(nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,93 +343,6 @@ func (t *Tree) getChildren(s *Storage) (map[string]*Tree, error) {
|
||||||
return children, nil
|
return children, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// inheritProviderConfig resolves all provider config inheritance after the
|
|
||||||
// tree is loaded.
|
|
||||||
//
|
|
||||||
// If there is a provider block without a config, look in the parent's Module
|
|
||||||
// block for a provider, and fetch that provider's configuration. If that
|
|
||||||
// doesn't exist, assume a default empty config. Implicit providers can still
|
|
||||||
// inherit their config all the way up from the root, so walk up the tree and
|
|
||||||
// copy the first matching provider into the module.
|
|
||||||
func (t *Tree) inheritProviderConfigs(stack []*Tree) {
|
|
||||||
// the recursive calls only append, so we don't need to worry about copying
|
|
||||||
// this slice.
|
|
||||||
stack = append(stack, t)
|
|
||||||
for _, c := range t.children {
|
|
||||||
c.inheritProviderConfigs(stack)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(stack) == 1 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
providers := make(map[string]*config.ProviderConfig)
|
|
||||||
missingProviders := make(map[string]bool)
|
|
||||||
|
|
||||||
for _, p := range t.config.ProviderConfigs {
|
|
||||||
providers[p.FullName()] = p
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, r := range t.config.Resources {
|
|
||||||
p := r.ProviderFullName()
|
|
||||||
if _, ok := providers[p]; !(ok || strings.Contains(p, ".")) {
|
|
||||||
missingProviders[p] = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// get our parent's module config block
|
|
||||||
parent := stack[len(stack)-2]
|
|
||||||
var parentModule *config.Module
|
|
||||||
for _, m := range parent.config.Modules {
|
|
||||||
if m.Name == t.name {
|
|
||||||
parentModule = m
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if parentModule == nil {
|
|
||||||
panic("can't be a module without a parent module config")
|
|
||||||
}
|
|
||||||
|
|
||||||
// now look for providers that need a config
|
|
||||||
for p, pc := range providers {
|
|
||||||
if len(pc.RawConfig.RawMap()) > 0 {
|
|
||||||
log.Printf("[TRACE] provider %q has a config, continuing", p)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// this provider has no config yet, check for one being passed in
|
|
||||||
parentProviderName, ok := parentModule.Providers[p]
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
var parentProvider *config.ProviderConfig
|
|
||||||
// there's a config for us in the parent module
|
|
||||||
for _, pp := range parent.config.ProviderConfigs {
|
|
||||||
if pp.FullName() == parentProviderName {
|
|
||||||
parentProvider = pp
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if parentProvider == nil {
|
|
||||||
// no config found, assume defaults
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy it in, but set an interpolation Scope.
|
|
||||||
// An interpolation Scope always need to have "root"
|
|
||||||
pc.Path = append([]string{RootName}, parent.path...)
|
|
||||||
pc.RawConfig = parentProvider.RawConfig
|
|
||||||
log.Printf("[TRACE] provider %q inheriting config from %q",
|
|
||||||
strings.Join(append(t.Path(), pc.FullName()), "."),
|
|
||||||
strings.Join(append(parent.Path(), parentProvider.FullName()), "."),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Path is the full path to this tree.
|
// Path is the full path to this tree.
|
||||||
func (t *Tree) Path() []string {
|
func (t *Tree) Path() []string {
|
||||||
return t.path
|
return t.path
|
||||||
|
|
|
@ -3,7 +3,6 @@ package module
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
@ -548,69 +547,6 @@ func TestTreeValidate_unknownModule(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTreeProviders_basic(t *testing.T) {
|
|
||||||
storage := testStorage(t, nil)
|
|
||||||
tree := NewTree("", testConfig(t, "basic-parent-providers"))
|
|
||||||
|
|
||||||
storage.Mode = GetModeGet
|
|
||||||
if err := tree.Load(storage); err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var a, b *Tree
|
|
||||||
for _, child := range tree.Children() {
|
|
||||||
if child.Name() == "a" {
|
|
||||||
a = child
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rootProviders := tree.config.ProviderConfigsByFullName()
|
|
||||||
topRaw := rootProviders["top.foo"]
|
|
||||||
|
|
||||||
if a == nil {
|
|
||||||
t.Fatal("could not find module 'a'")
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, child := range a.Children() {
|
|
||||||
if child.Name() == "c" {
|
|
||||||
b = child
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if b == nil {
|
|
||||||
t.Fatal("could not find module 'c'")
|
|
||||||
}
|
|
||||||
|
|
||||||
aProviders := a.config.ProviderConfigsByFullName()
|
|
||||||
bottomRaw := aProviders["bottom.foo"]
|
|
||||||
bProviders := b.config.ProviderConfigsByFullName()
|
|
||||||
bBottom := bProviders["bottom"]
|
|
||||||
|
|
||||||
// compare the configs
|
|
||||||
// top.foo should have been copied to a.top
|
|
||||||
aTop := aProviders["top"]
|
|
||||||
if !reflect.DeepEqual(aTop.RawConfig.RawMap(), topRaw.RawConfig.RawMap()) {
|
|
||||||
log.Fatalf("expected config %#v, got %#v",
|
|
||||||
topRaw.RawConfig.RawMap(),
|
|
||||||
aTop.RawConfig.RawMap(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !reflect.DeepEqual(aTop.Path, []string{RootName}) {
|
|
||||||
log.Fatalf(`expected scope for "top": {"root"}, got %#v`, aTop.Path)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !reflect.DeepEqual(bBottom.RawConfig.RawMap(), bottomRaw.RawConfig.RawMap()) {
|
|
||||||
t.Fatalf("expected config %#v, got %#v",
|
|
||||||
bottomRaw.RawConfig.RawMap(),
|
|
||||||
bBottom.RawConfig.RawMap(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(bBottom.Path, []string{RootName, "a"}) {
|
|
||||||
t.Fatalf(`expected scope for "bottom": {"root", "a"}, got %#v`, bBottom.Path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTreeLoad_conflictingSubmoduleNames(t *testing.T) {
|
func TestTreeLoad_conflictingSubmoduleNames(t *testing.T) {
|
||||||
storage := testStorage(t, nil)
|
storage := testStorage(t, nil)
|
||||||
tree := NewTree("", testConfig(t, "conficting-submodule-names"))
|
tree := NewTree("", testConfig(t, "conficting-submodule-names"))
|
||||||
|
|
Loading…
Reference in New Issue