From e08dc05f540ee0e1c2d7d8e0aa60805b5ffc0a1b Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 27 Jan 2015 10:13:50 -0800 Subject: [PATCH] terraform: State.ModuleOrphans --- terraform/state.go | 23 ++++++++++++++++ terraform/state_test.go | 26 +++++++++++++++++++ .../state-module-orphans/bar/main.tf | 1 + .../state-module-orphans/main.tf | 3 +++ 4 files changed, 53 insertions(+) create mode 100644 terraform/test-fixtures/state-module-orphans/bar/main.tf create mode 100644 terraform/test-fixtures/state-module-orphans/main.tf diff --git a/terraform/state.go b/terraform/state.go index dea8fe9610..ccb4b57372 100644 --- a/terraform/state.go +++ b/terraform/state.go @@ -100,6 +100,29 @@ func (s *State) ModuleByPath(path []string) *ModuleState { return nil } +// ModuleOrphans returns all the module orphans in this state by +// returning their full paths. These paths can be used with ModuleByPath +// 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{}{} + } + + // Go over the direct children and find any that aren't in our + // keys. + var orphans [][]string + for _, m := range s.Children(path) { + if _, ok := childrenKeys[m.Path[len(m.Path)-1]]; ok { + continue + } + + orphans = append(orphans, m.Path) + } + + return orphans +} + // RootModule returns the ModuleState for the root module func (s *State) RootModule() *ModuleState { root := s.ModuleByPath(rootModulePath) diff --git a/terraform/state_test.go b/terraform/state_test.go index 7a5554651d..f7889dc6de 100644 --- a/terraform/state_test.go +++ b/terraform/state_test.go @@ -59,6 +59,32 @@ func TestStateAddModule(t *testing.T) { } } +func TestStateModuleOrphans(t *testing.T) { + state := &State{ + Modules: []*ModuleState{ + &ModuleState{ + Path: RootModulePath, + }, + &ModuleState{ + Path: []string{RootModuleName, "foo"}, + }, + &ModuleState{ + Path: []string{RootModuleName, "bar"}, + }, + }, + } + + config := testModule(t, "state-module-orphans").Config() + actual := state.ModuleOrphans(RootModulePath, config) + expected := [][]string{ + []string{RootModuleName, "foo"}, + } + + if !reflect.DeepEqual(actual, expected) { + t.Fatalf("bad: %#v", actual) + } +} + func TestInstanceState_MergeDiff(t *testing.T) { is := InstanceState{ ID: "foo", diff --git a/terraform/test-fixtures/state-module-orphans/bar/main.tf b/terraform/test-fixtures/state-module-orphans/bar/main.tf new file mode 100644 index 0000000000..c01ade299a --- /dev/null +++ b/terraform/test-fixtures/state-module-orphans/bar/main.tf @@ -0,0 +1 @@ +# Nothing diff --git a/terraform/test-fixtures/state-module-orphans/main.tf b/terraform/test-fixtures/state-module-orphans/main.tf new file mode 100644 index 0000000000..f009f19246 --- /dev/null +++ b/terraform/test-fixtures/state-module-orphans/main.tf @@ -0,0 +1,3 @@ +module "bar" { + source = "./bar" +}