github.com/trawler/terraform@v0.10.8-0.20171106022149-4b1c7a1d9b48/terraform/transform_orphan_output.go (about) 1 package terraform 2 3 import ( 4 "log" 5 6 "github.com/hashicorp/terraform/config" 7 "github.com/hashicorp/terraform/config/module" 8 ) 9 10 // OrphanOutputTransformer finds the outputs that aren't present 11 // in the given config that are in the state and adds them to the graph 12 // for deletion. 13 type OrphanOutputTransformer struct { 14 Module *module.Tree // Root module 15 State *State // State is the root state 16 } 17 18 func (t *OrphanOutputTransformer) Transform(g *Graph) error { 19 if t.State == nil { 20 log.Printf("[DEBUG] No state, no orphan outputs") 21 return nil 22 } 23 24 return t.transform(g, t.Module) 25 } 26 27 func (t *OrphanOutputTransformer) transform(g *Graph, m *module.Tree) error { 28 // Get our configuration, and recurse into children 29 var c *config.Config 30 if m != nil { 31 c = m.Config() 32 for _, child := range m.Children() { 33 if err := t.transform(g, child); err != nil { 34 return err 35 } 36 } 37 } 38 39 // Get the state. If there is no state, then we have no orphans! 40 path := normalizeModulePath(m.Path()) 41 state := t.State.ModuleByPath(path) 42 if state == nil { 43 return nil 44 } 45 46 // Make a map of the valid outputs 47 valid := make(map[string]struct{}) 48 for _, o := range c.Outputs { 49 valid[o.Name] = struct{}{} 50 } 51 52 // Go through the outputs and find the ones that aren't in our config. 53 for n, _ := range state.Outputs { 54 // If it is in the valid map, then ignore 55 if _, ok := valid[n]; ok { 56 continue 57 } 58 59 // Orphan! 60 g.Add(&NodeOutputOrphan{OutputName: n, PathValue: path}) 61 } 62 63 return nil 64 }