diff --git a/terraform/context_test.go b/terraform/context_test.go index cf25714a0..da806dfa7 100644 --- a/terraform/context_test.go +++ b/terraform/context_test.go @@ -204,8 +204,7 @@ func TestContext2Plan_moduleMultiVar(t *testing.T) { } } -/* -func TestContextPlan_moduleOrphans(t *testing.T) { +func TestContext2Plan_moduleOrphans(t *testing.T) { m := testModule(t, "plan-modules-remove") p := testProvider("aws") p.DiffFn = testDiffFn @@ -224,7 +223,7 @@ func TestContextPlan_moduleOrphans(t *testing.T) { }, }, } - ctx := testContext(t, &ContextOpts{ + ctx := testContext2(t, &ContextOpts{ Module: m, Providers: map[string]ResourceProviderFactory{ "aws": testProviderFuncFixed(p), @@ -244,6 +243,7 @@ func TestContextPlan_moduleOrphans(t *testing.T) { } } +/* func TestContextPlan_moduleProviderInherit(t *testing.T) { var l sync.Mutex var calls []string diff --git a/terraform/eval_diff.go b/terraform/eval_diff.go index 18ced69e0..12a2115cf 100644 --- a/terraform/eval_diff.go +++ b/terraform/eval_diff.go @@ -96,6 +96,56 @@ func (n *EvalDiff) Type() EvalType { return EvalTypeInstanceState } +// EvalDiffDestroy is an EvalNode implementation that returns a plain +// destroy diff. +type EvalDiffDestroy struct { + Info *InstanceInfo + State EvalNode + Output *InstanceDiff +} + +func (n *EvalDiffDestroy) Args() ([]EvalNode, []EvalType) { + return []EvalNode{n.State}, []EvalType{EvalTypeInstanceState} +} + +// TODO: test +func (n *EvalDiffDestroy) Eval( + ctx EvalContext, args []interface{}) (interface{}, error) { + // Extract our arguments + var state *InstanceState + if args[0] != nil { + state = args[0].(*InstanceState) + } + + // Call pre-diff hook + err := ctx.Hook(func(h Hook) (HookAction, error) { + return h.PreDiff(n.Info, state) + }) + if err != nil { + return nil, err + } + + // The diff + diff := &InstanceDiff{Destroy: true} + + // Call post-diff hook + err = ctx.Hook(func(h Hook) (HookAction, error) { + return h.PostDiff(n.Info, diff) + }) + if err != nil { + return nil, err + } + + // Update our output + *n.Output = *diff + + return nil, nil +} + +func (n *EvalDiffDestroy) Type() EvalType { + return EvalTypeNull +} + // EvalWriteDiff is an EvalNode implementation that writes the diff to // the full diff. type EvalWriteDiff struct { diff --git a/terraform/state.go b/terraform/state.go index ccb4b5737..8bab90c95 100644 --- a/terraform/state.go +++ b/terraform/state.go @@ -105,8 +105,10 @@ func (s *State) ModuleByPath(path []string) *ModuleState { // to return the actual state. func (s *State) ModuleOrphans(path []string, c *config.Config) [][]string { childrenKeys := make(map[string]struct{}) - for _, m := range c.Modules { - childrenKeys[m.Name] = struct{}{} + if c != nil { + for _, m := range c.Modules { + childrenKeys[m.Name] = struct{}{} + } } // Go over the direct children and find any that aren't in our @@ -301,12 +303,14 @@ func (m *ModuleState) Orphans(c *config.Config) []string { keys[k] = struct{}{} } - for _, r := range c.Resources { - delete(keys, r.Id()) + if c != nil { + for _, r := range c.Resources { + delete(keys, r.Id()) - for k, _ := range keys { - if strings.HasPrefix(k, r.Id()+".") { - delete(keys, k) + for k, _ := range keys { + if strings.HasPrefix(k, r.Id()+".") { + delete(keys, k) + } } } } diff --git a/terraform/state_test.go b/terraform/state_test.go index f7889dc6d..8211a35b5 100644 --- a/terraform/state_test.go +++ b/terraform/state_test.go @@ -85,6 +85,32 @@ func TestStateModuleOrphans(t *testing.T) { } } +func TestStateModuleOrphans_nilConfig(t *testing.T) { + state := &State{ + Modules: []*ModuleState{ + &ModuleState{ + Path: RootModulePath, + }, + &ModuleState{ + Path: []string{RootModuleName, "foo"}, + }, + &ModuleState{ + Path: []string{RootModuleName, "bar"}, + }, + }, + } + + actual := state.ModuleOrphans(RootModulePath, nil) + expected := [][]string{ + []string{RootModuleName, "foo"}, + []string{RootModuleName, "bar"}, + } + + if !reflect.DeepEqual(actual, expected) { + t.Fatalf("bad: %#v", actual) + } +} + func TestInstanceState_MergeDiff(t *testing.T) { is := InstanceState{ ID: "foo", diff --git a/terraform/transform_config.go b/terraform/transform_config.go index 21e08930d..e62074068 100644 --- a/terraform/transform_config.go +++ b/terraform/transform_config.go @@ -29,8 +29,7 @@ func (t *ConfigTransformer) Transform(g *Graph) error { // Get the module we care about module := t.Module.Child(g.Path[1:]) if module == nil { - return fmt.Errorf( - "module not found for path: %#v", g.Path[1:]) + return nil } // Get the configuration for this module diff --git a/terraform/transform_expand.go b/terraform/transform_expand.go index 6cdda3e39..85d660206 100644 --- a/terraform/transform_expand.go +++ b/terraform/transform_expand.go @@ -1,6 +1,8 @@ package terraform import ( + "log" + "github.com/hashicorp/terraform/dag" ) @@ -41,5 +43,19 @@ func (t *ExpandTransform) Transform(v dag.Vertex) (dag.Vertex, error) { } // Expand the subgraph! + log.Printf("[DEBUG] vertex %s: static expanding", dag.VertexName(ev)) return ev.Expand(t.Builder) } + +type GraphNodeBasicSubgraph struct { + NameValue string + Graph *Graph +} + +func (n *GraphNodeBasicSubgraph) Name() string { + return n.NameValue +} + +func (n *GraphNodeBasicSubgraph) Subgraph() *Graph { + return n.Graph +} diff --git a/terraform/transform_orphan.go b/terraform/transform_orphan.go index 15d925221..5c23f6147 100644 --- a/terraform/transform_orphan.go +++ b/terraform/transform_orphan.go @@ -3,6 +3,7 @@ package terraform import ( "fmt" + "github.com/hashicorp/terraform/config" "github.com/hashicorp/terraform/config/module" "github.com/hashicorp/terraform/dag" ) @@ -20,13 +21,10 @@ type OrphanTransformer struct { } func (t *OrphanTransformer) Transform(g *Graph) error { - module := t.Module.Child(g.Path[1:]) - if module == nil { - panic(fmt.Sprintf( - "module not found for path: %#v", - g.Path[1:])) + var config *config.Config + if module := t.Module.Child(g.Path[1:]); module != nil { + config = module.Config() } - config := module.Config() var resourceVertexes []dag.Vertex if state := t.State.ModuleByPath(g.Path); state != nil {