From f0727501c1b7c7d5f57dcf404837c33c60b1f6c8 Mon Sep 17 00:00:00 2001 From: James Bardin Date: Tue, 31 Oct 2017 15:58:24 -0400 Subject: [PATCH] WIP only add missing providers at the root level When looking for providers to connect to resources, walk up the resource path to find the appropriate provider. --- terraform/transform_provider.go | 56 +++++++++++++++++++++++----- terraform/transform_provider_test.go | 2 +- 2 files changed, 47 insertions(+), 11 deletions(-) diff --git a/terraform/transform_provider.go b/terraform/transform_provider.go index baf3016b9..0bbbd1d99 100644 --- a/terraform/transform_provider.go +++ b/terraform/transform_provider.go @@ -27,6 +27,7 @@ type GraphNodeCloseProvider interface { // a provider must implement. ProvidedBy must return the name of the provider // to use. type GraphNodeProviderConsumer interface { + // TODO: make this return s string instead of a []string ProvidedBy() []string } @@ -41,18 +42,45 @@ func (t *ProviderTransformer) Transform(g *Graph) error { m := providerVertexMap(g) for _, v := range g.Vertices() { if pv, ok := v.(GraphNodeProviderConsumer); ok { - for _, p := range pv.ProvidedBy() { - target := m[providerMapKey(p, pv)] - if target == nil { - println(fmt.Sprintf("%#v\n\n%#v", m, providerMapKey(p, pv))) - err = multierror.Append(err, fmt.Errorf( - "%s: provider %s couldn't be found", - dag.VertexName(v), p)) - continue + p := pv.ProvidedBy()[0] + + key := providerMapKey(p, pv) + target := m[key] + + sp, ok := pv.(GraphNodeSubPath) + if !ok && target == nil { + // no target, and no path to walk up + err = multierror.Append(err, fmt.Errorf( + "%s: provider %s couldn't be found", + dag.VertexName(v), p)) + break + } + + // if we don't have a provider at this level, walk up the path looking for one + for i := 1; target == nil; i++ { + pathPrefix := "" + raw := normalizeModulePath(sp.Path()) + if len(raw) < i { + break } - g.Connect(dag.BasicEdge(v, target)) + raw = raw[:len(raw)-i] + + if len(raw) > len(rootModulePath) { + pathPrefix = modulePrefixStr(raw) + "." + } + key = pathPrefix + p + target = m[key] } + + if target == nil { + err = multierror.Append(err, fmt.Errorf( + "%s: provider %s couldn't be found", + dag.VertexName(v), p)) + break + } + + g.Connect(dag.BasicEdge(v, target)) } } @@ -173,12 +201,17 @@ func (t *MissingProviderTransformer) Transform(g *Graph) error { } key := providerMapKey(p, pv) + + // TODO: jbardin come back to this + // only adding root level missing providers + key = p if _, ok := m[key]; ok { // This provider already exists as a configure node continue } // If the provider has an alias in it, we just want the type + // TODO: jbardin -- stop adding aliased providers altogether ptype := p if idx := strings.IndexRune(p, '.'); idx != -1 { ptype = p[:idx] @@ -195,7 +228,10 @@ func (t *MissingProviderTransformer) Transform(g *Graph) error { // Add the missing provider node to the graph v := t.Concrete(&NodeAbstractProvider{ NameValue: p, - PathValue: path, + + // TODO: jbardin come back to this + // only adding root level missing providers + //PathValue: path, }).(dag.Vertex) m[key] = g.Add(v) } diff --git a/terraform/transform_provider_test.go b/terraform/transform_provider_test.go index b9f52a1f7..29561a246 100644 --- a/terraform/transform_provider_test.go +++ b/terraform/transform_provider_test.go @@ -339,7 +339,7 @@ func TestParentProviderTransformer_moduleGrandchild(t *testing.T) { actual := strings.TrimSpace(g.String()) expected := strings.TrimSpace(testTransformParentProviderModuleGrandchildStr) if actual != expected { - t.Fatalf("bad:\n\n%s", actual) + t.Fatalf("expected:\n%s\n\ngot:\n%s", expected, actual) } }