From 8f5836768050e459ee07152d7a9d7ee23ff16a74 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 1 May 2015 18:08:06 -0700 Subject: [PATCH] terraform: missing providers need to do dependencies --- terraform/graph.go | 12 +++++++++ terraform/graph_builder_test.go | 16 ++++++++++++ terraform/transform_module.go | 43 +++++++++++++++++++++++++++++++++ terraform/transform_provider.go | 33 +++++++++++++++++++++++++ 4 files changed, 104 insertions(+) diff --git a/terraform/graph.go b/terraform/graph.go index 6fe78207fe..6744a931e9 100644 --- a/terraform/graph.go +++ b/terraform/graph.go @@ -69,6 +69,18 @@ func (g *Graph) Remove(v dag.Vertex) dag.Vertex { return g.Graph.Remove(v) } +// Replace is the same as dag.Graph.Replace +func (g *Graph) Replace(o, n dag.Vertex) bool { + // Go through and update our lookaside to point to the new vertex + for k, v := range g.dependableMap { + if v == o { + g.dependableMap[k] = n + } + } + + return g.Graph.Replace(o, n) +} + // ConnectDependent connects a GraphNodeDependent to all of its // GraphNodeDependables. It returns the list of dependents it was // unable to connect to. diff --git a/terraform/graph_builder_test.go b/terraform/graph_builder_test.go index 0f66947fcf..4811d78664 100644 --- a/terraform/graph_builder_test.go +++ b/terraform/graph_builder_test.go @@ -136,6 +136,22 @@ func TestBuiltinGraphBuilder_cbdDepNonCbd_errorsWhenVerbose(t *testing.T) { } } +func TestBuiltinGraphBuilder_fuck(t *testing.T) { + b := &BuiltinGraphBuilder{ + Providers: []string{"aws"}, + Root: testModule(t, "validate-module-pc-inherit-unused"), + Validate: true, + } + + g, err := b.Build(RootModulePath) + if err != nil { + t.Fatalf("err: %s", err) + } + + println(g.String()) + t.FailNow() +} + /* TODO: This exposes a really bad bug we need to fix after we merge the f-ast-branch. This bug still exists in master. diff --git a/terraform/transform_module.go b/terraform/transform_module.go index 7733fe5784..7154ff70b2 100644 --- a/terraform/transform_module.go +++ b/terraform/transform_module.go @@ -33,6 +33,49 @@ func (t *ModuleInputTransformer) Transform(g *Graph) error { return nil } +// ModuleDestroyTransformer is a GraphTransformer that adds a node +// to the graph that will just mark the full module for destroy in +// the destroy scenario. +type ModuleDestroyTransformer struct{} + +func (t *ModuleDestroyTransformer) Transform(g *Graph) error { + // Create the node + n := &graphNodeModuleDestroy{Path: g.Path} + + // Add it to the graph + g.Add(n) + + // Connect the inputs to the bottom of the graph so that it happens + // first. + for _, v := range g.Vertices() { + if v == n { + continue + } + + if g.DownEdges(v).Len() == 0 { + g.Connect(dag.BasicEdge(v, n)) + } + } + + return nil +} + +type graphNodeModuleDestroy struct { + Path []string +} + +func (n *graphNodeModuleDestroy) Name() string { + return "module destroy (for plan)" +} + +// GraphNodeEvalable impl. +func (n *graphNodeModuleDestroy) EvalTree() EvalNode { + return &EvalOpFilter{ + Ops: []walkOperation{walkPlanDestroy}, + Node: &EvalDiffDestroyModule{Path: n.Path}, + } +} + type graphNodeModuleInput struct { Variables map[string]string } diff --git a/terraform/transform_provider.go b/terraform/transform_provider.go index 0b625e5fa0..2e111ee820 100644 --- a/terraform/transform_provider.go +++ b/terraform/transform_provider.go @@ -190,6 +190,21 @@ func (n *graphNodeDisabledProvider) DotOrigin() bool { return true } +// GraphNodeDependable impl. +func (n *graphNodeDisabledProvider) DependableName() []string { + return []string{"provider." + n.ProviderName()} +} + +// GraphNodeProvider impl. +func (n *graphNodeDisabledProvider) ProviderName() string { + return n.GraphNodeProvider.ProviderName() +} + +// GraphNodeProvider impl. +func (n *graphNodeDisabledProvider) ProviderConfig() *config.RawConfig { + return n.GraphNodeProvider.ProviderConfig() +} + type graphNodeMissingProvider struct { ProviderNameValue string } @@ -264,3 +279,21 @@ func (n *graphNodeMissingProviderFlat) ProviderName() string { "%s.%s", modulePrefixStr(n.PathValue), n.graphNodeMissingProvider.ProviderName()) } + +func (n *graphNodeMissingProviderFlat) DependentOn() []string { + var result []string + + // If we're in a module, then depend on our parent's provider + if len(n.PathValue) > 1 { + prefix := modulePrefixStr(n.PathValue[:len(n.PathValue)-1]) + if prefix != "" { + prefix += "." + } + + result = append(result, fmt.Sprintf( + "%s%s", + prefix, n.graphNodeMissingProvider.Name())) + } + + return result +}