terraform: orphan outputs are deleted from the state

This commit is contained in:
Mitchell Hashimoto 2016-09-18 21:45:19 -07:00
parent 38b9f7794d
commit 2e8cb94a5e
No known key found for this signature in database
GPG Key ID: 744E147AA52F5B0A
4 changed files with 102 additions and 0 deletions

View File

@ -54,6 +54,9 @@ func (b *ApplyGraphBuilder) Steps() []GraphTransformer {
State: b.State, State: b.State,
}, },
// Create orphan output nodes
&OrphanOutputTransformer{Module: b.Module, State: b.State},
// Attach the state // Attach the state
&AttachStateTransformer{State: b.State}, &AttachStateTransformer{State: b.State},

View File

@ -0,0 +1,32 @@
package terraform
import (
"fmt"
)
// NodeOutputOrphan represents an output that is an orphan.
type NodeOutputOrphan struct {
OutputName string
PathValue []string
}
func (n *NodeOutputOrphan) Name() string {
result := fmt.Sprintf("output.%s (orphan)", n.OutputName)
if len(n.PathValue) > 1 {
result = fmt.Sprintf("%s.%s", modulePrefixStr(n.PathValue), result)
}
return result
}
// GraphNodeSubPath
func (n *NodeOutputOrphan) Path() []string {
return n.PathValue
}
// GraphNodeEvalable
func (n *NodeOutputOrphan) EvalTree() EvalNode {
return &EvalDeleteOutput{
Name: n.OutputName,
}
}

View File

@ -0,0 +1,64 @@
package terraform
import (
"log"
"github.com/hashicorp/terraform/config"
"github.com/hashicorp/terraform/config/module"
)
// OrphanOutputTransformer finds the outputs that aren't present
// in the given config that are in the state and adds them to the graph
// for deletion.
type OrphanOutputTransformer struct {
Module *module.Tree // Root module
State *State // State is the root state
}
func (t *OrphanOutputTransformer) Transform(g *Graph) error {
if t.State == nil {
log.Printf("[DEBUG] No state, no orphan outputs")
return nil
}
return t.transform(g, t.Module)
}
func (t *OrphanOutputTransformer) transform(g *Graph, m *module.Tree) error {
// Get our configuration, and recurse into children
var c *config.Config
if m != nil {
c = m.Config()
for _, child := range m.Children() {
if err := t.transform(g, child); err != nil {
return err
}
}
}
// Get the state. If there is no state, then we have no orphans!
path := normalizeModulePath(m.Path())
state := t.State.ModuleByPath(path)
if state == nil {
return nil
}
// Make a map of the valid outputs
valid := make(map[string]struct{})
for _, o := range c.Outputs {
valid[o.Name] = struct{}{}
}
// Go through the outputs and find the ones that aren't in our config.
for n, _ := range state.Outputs {
// If it is in the valid map, then ignore
if _, ok := valid[n]; ok {
continue
}
// Orphan!
g.Add(&NodeOutputOrphan{OutputName: n, PathValue: path})
}
return nil
}

View File

@ -16,6 +16,9 @@ type GraphNodeOutput interface {
// AddOutputOrphanTransformer is a transformer that adds output orphans // AddOutputOrphanTransformer is a transformer that adds output orphans
// to the graph. Output orphans are outputs that are no longer in the // to the graph. Output orphans are outputs that are no longer in the
// configuration and therefore need to be removed from the state. // configuration and therefore need to be removed from the state.
//
// NOTE: This is the _old_ way to add output orphans that is used with
// legacy graph builders. The new way is OrphanOutputTransformer.
type AddOutputOrphanTransformer struct { type AddOutputOrphanTransformer struct {
State *State State *State
} }