kubeform.dev/terraform-backend-sdk@v0.0.0-20220310143633-45f07fe731c5/terraform/transform_output.go (about) 1 package terraform 2 3 import ( 4 "log" 5 6 "kubeform.dev/terraform-backend-sdk/addrs" 7 "kubeform.dev/terraform-backend-sdk/configs" 8 "kubeform.dev/terraform-backend-sdk/dag" 9 "kubeform.dev/terraform-backend-sdk/plans" 10 ) 11 12 // OutputTransformer is a GraphTransformer that adds all the outputs 13 // in the configuration to the graph. 14 // 15 // This is done for the apply graph builder even if dependent nodes 16 // aren't changing since there is no downside: the state will be available 17 // even if the dependent items aren't changing. 18 type OutputTransformer struct { 19 Config *configs.Config 20 Changes *plans.Changes 21 22 // if this is a planed destroy, root outputs are still in the configuration 23 // so we need to record that we wish to remove them 24 Destroy bool 25 } 26 27 func (t *OutputTransformer) Transform(g *Graph) error { 28 return t.transform(g, t.Config) 29 } 30 31 func (t *OutputTransformer) transform(g *Graph, c *configs.Config) error { 32 // If we have no config then there can be no outputs. 33 if c == nil { 34 return nil 35 } 36 37 // Transform all the children. We must do this first because 38 // we can reference module outputs and they must show up in the 39 // reference map. 40 for _, cc := range c.Children { 41 if err := t.transform(g, cc); err != nil { 42 return err 43 } 44 } 45 46 // Add outputs to the graph, which will be dynamically expanded 47 // into NodeApplyableOutputs to reflect possible expansion 48 // through the presence of "count" or "for_each" on the modules. 49 50 var changes []*plans.OutputChangeSrc 51 if t.Changes != nil { 52 changes = t.Changes.Outputs 53 } 54 55 for _, o := range c.Module.Outputs { 56 addr := addrs.OutputValue{Name: o.Name} 57 58 var rootChange *plans.OutputChangeSrc 59 for _, c := range changes { 60 if c.Addr.Module.IsRoot() && c.Addr.OutputValue.Name == o.Name { 61 rootChange = c 62 } 63 } 64 65 destroy := t.Destroy 66 if rootChange != nil { 67 destroy = rootChange.Action == plans.Delete 68 } 69 70 // If this is a root output, we add the apply or destroy node directly, 71 // as the root modules does not expand. 72 73 var node dag.Vertex 74 switch { 75 case c.Path.IsRoot() && destroy: 76 node = &NodeDestroyableOutput{ 77 Addr: addr.Absolute(addrs.RootModuleInstance), 78 Config: o, 79 } 80 81 case c.Path.IsRoot(): 82 node = &NodeApplyableOutput{ 83 Addr: addr.Absolute(addrs.RootModuleInstance), 84 Config: o, 85 Change: rootChange, 86 } 87 88 default: 89 node = &nodeExpandOutput{ 90 Addr: addr, 91 Module: c.Path, 92 Config: o, 93 Changes: changes, 94 Destroy: t.Destroy, 95 } 96 } 97 98 log.Printf("[TRACE] OutputTransformer: adding %s as %T", o.Name, node) 99 g.Add(node) 100 } 101 102 return nil 103 }