rewrite the ProviderConfigTransformer
It's become apparent that passing in a provider config for an implicitly used provider would be very useful. While the ProviderConfigTransformer efficiently added providers to the graph, the algorithm was reversed from what would be needed to allow overriding implicit providers. Change the ProviderConfigTransformer to fist add all configured provider, even if they are empty stubs. Then run through all providers being passed in from the parent, and replace the provider nodes we created with proxies, and add implicit proxies where none existed. The extra nodes will then be pruned later.
This commit is contained in:
parent
aef082d1ec
commit
8bf270daa9
|
@ -405,6 +405,8 @@ type ProviderConfigTransformer struct {
|
||||||
// each provider node is stored here so that the proxy nodes can look up
|
// each provider node is stored here so that the proxy nodes can look up
|
||||||
// their targets by name.
|
// their targets by name.
|
||||||
providers map[string]GraphNodeProvider
|
providers map[string]GraphNodeProvider
|
||||||
|
// record providers that can be overriden with a proxy
|
||||||
|
proxiable map[string]bool
|
||||||
|
|
||||||
// Module is the module to add resources from.
|
// Module is the module to add resources from.
|
||||||
Module *module.Tree
|
Module *module.Tree
|
||||||
|
@ -422,6 +424,7 @@ func (t *ProviderConfigTransformer) Transform(g *Graph) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
t.providers = make(map[string]GraphNodeProvider)
|
t.providers = make(map[string]GraphNodeProvider)
|
||||||
|
t.proxiable = make(map[string]bool)
|
||||||
|
|
||||||
// Start the transformation process
|
// Start the transformation process
|
||||||
if err := t.transform(g, t.Module); err != nil {
|
if err := t.transform(g, t.Module); err != nil {
|
||||||
|
@ -464,19 +467,13 @@ func (t *ProviderConfigTransformer) transformSingle(g *Graph, m *module.Tree) er
|
||||||
path = append([]string{RootModuleName}, path...)
|
path = append([]string{RootModuleName}, path...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// add all provider configs
|
// add all providers from the configuration
|
||||||
for _, p := range conf.ProviderConfigs {
|
for _, p := range conf.ProviderConfigs {
|
||||||
name := p.Name
|
name := p.Name
|
||||||
if p.Alias != "" {
|
if p.Alias != "" {
|
||||||
name += "." + p.Alias
|
name += "." + p.Alias
|
||||||
}
|
}
|
||||||
|
|
||||||
// if this is an empty config placeholder to accept a provier from a
|
|
||||||
// parent module, add a proxy and continue.
|
|
||||||
if t.addProxyProvider(g, m, p, name) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
v := t.Concrete(&NodeAbstractProvider{
|
v := t.Concrete(&NodeAbstractProvider{
|
||||||
NameValue: name,
|
NameValue: name,
|
||||||
PathValue: path,
|
PathValue: path,
|
||||||
|
@ -484,26 +481,29 @@ func (t *ProviderConfigTransformer) transformSingle(g *Graph, m *module.Tree) er
|
||||||
|
|
||||||
// Add it to the graph
|
// Add it to the graph
|
||||||
g.Add(v)
|
g.Add(v)
|
||||||
t.providers[ResolveProviderName(name, path)] = v.(GraphNodeProvider)
|
fullName := ResolveProviderName(name, path)
|
||||||
|
t.providers[fullName] = v.(GraphNodeProvider)
|
||||||
|
t.proxiable[fullName] = len(p.RawConfig.RawMap()) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
// Now replace the provider nodes with proxy nodes if a provider was being
|
||||||
|
// passed in, and create implicit proxies if there was no config. Any extra
|
||||||
|
// proxies will be removed in the prune step.
|
||||||
|
return t.addProxyProviders(g, m)
|
||||||
}
|
}
|
||||||
|
|
||||||
// add a ProxyProviderConfig if this was inherited from a parent module. Return
|
func (t *ProviderConfigTransformer) addProxyProviders(g *Graph, m *module.Tree) error {
|
||||||
// whether the proxy was added to the graph or not.
|
|
||||||
func (t *ProviderConfigTransformer) addProxyProvider(g *Graph, m *module.Tree, pc *config.ProviderConfig, name string) bool {
|
|
||||||
path := m.Path()
|
path := m.Path()
|
||||||
|
|
||||||
// This isn't a proxy if there's a config, or we're at the root
|
// can't add proxies at the root
|
||||||
if len(pc.RawConfig.RawMap()) > 0 || len(path) == 0 {
|
if len(path) == 0 {
|
||||||
return false
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
parentPath := path[:len(path)-1]
|
parentPath := path[:len(path)-1]
|
||||||
parent := t.Module.Child(parentPath)
|
parent := t.Module.Child(parentPath)
|
||||||
if parent == nil {
|
if parent == nil {
|
||||||
return false
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var parentCfg *config.Module
|
var parentCfg *config.Module
|
||||||
|
@ -515,35 +515,47 @@ func (t *ProviderConfigTransformer) addProxyProvider(g *Graph, m *module.Tree, p
|
||||||
}
|
}
|
||||||
|
|
||||||
if parentCfg == nil {
|
if parentCfg == nil {
|
||||||
panic("immaculately conceived module " + m.Name())
|
// this can't really happen during normal execution.
|
||||||
|
return fmt.Errorf("parent module config not found for %s", m.Name())
|
||||||
}
|
}
|
||||||
|
|
||||||
parentProviderName, ok := parentCfg.Providers[name]
|
// Go through all the providers the parent is passing in, and add proxies to
|
||||||
if !ok {
|
// the parent provider nodes.
|
||||||
// this provider isn't listed in a parent module block, so we just have
|
for name, parentName := range parentCfg.Providers {
|
||||||
// an empty config
|
fullName := ResolveProviderName(name, path)
|
||||||
return false
|
fullParentName := ResolveProviderName(parentName, parentPath)
|
||||||
|
parentProvider := t.providers[fullParentName]
|
||||||
|
|
||||||
|
if parentProvider == nil {
|
||||||
|
return fmt.Errorf("missing provider %s", fullParentName)
|
||||||
|
}
|
||||||
|
|
||||||
|
proxy := &graphNodeProxyProvider{
|
||||||
|
nameValue: name,
|
||||||
|
path: path,
|
||||||
|
target: parentProvider,
|
||||||
|
}
|
||||||
|
|
||||||
|
concreteProvider := t.providers[fullName]
|
||||||
|
|
||||||
|
// replace the concrete node with the provider passed in
|
||||||
|
if concreteProvider != nil && t.proxiable[fullName] {
|
||||||
|
g.Replace(concreteProvider, proxy)
|
||||||
|
t.providers[fullName] = proxy
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// aliased providers can't be implicitly passed in
|
||||||
|
if strings.Contains(name, ".") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// There was no concrete provider, so add this as an implicit provider.
|
||||||
|
// The extra proxy will be pruned later if it's unused.
|
||||||
|
g.Add(proxy)
|
||||||
|
t.providers[fullName] = proxy
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
// the parent module is passing in a provider
|
|
||||||
fullParentName := ResolveProviderName(parentProviderName, parentPath)
|
|
||||||
parentProvider := t.providers[fullParentName]
|
|
||||||
|
|
||||||
if parentProvider == nil {
|
|
||||||
log.Printf("[ERROR] missing provider %s in module %s", parentProviderName, m.Name())
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
v := &graphNodeProxyProvider{
|
|
||||||
nameValue: name,
|
|
||||||
path: path,
|
|
||||||
target: parentProvider,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add it to the graph
|
|
||||||
g.Add(v)
|
|
||||||
t.providers[ResolveProviderName(name, path)] = v
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *ProviderConfigTransformer) attachProviderConfigs(g *Graph) error {
|
func (t *ProviderConfigTransformer) attachProviderConfigs(g *Graph) error {
|
||||||
|
|
Loading…
Reference in New Issue