terraform: untainted resource depends on tainted resource if it exists

This commit is contained in:
Mitchell Hashimoto 2015-01-27 21:06:46 -08:00
parent d2f3dc8d1f
commit e1d3f308a6
3 changed files with 44 additions and 21 deletions

View File

@ -55,23 +55,12 @@ func (g *Graph) Add(v dag.Vertex) dag.Vertex {
// GraphNodeDependables. It returns the list of dependents it was // GraphNodeDependables. It returns the list of dependents it was
// unable to connect to. // unable to connect to.
func (g *Graph) ConnectDependent(raw dag.Vertex) []string { func (g *Graph) ConnectDependent(raw dag.Vertex) []string {
g.once.Do(g.init)
v, ok := raw.(GraphNodeDependent) v, ok := raw.(GraphNodeDependent)
if !ok { if !ok {
return nil return nil
} }
var missing []string return g.ConnectTo(v, v.DependentOn())
for _, t := range v.DependentOn() {
if dest := g.dependableMap[t]; dest != nil {
g.Connect(dag.BasicEdge(v, dest))
} else {
missing = append(missing, t)
}
}
return missing
} }
// ConnectDependents goes through the graph, connecting all the // ConnectDependents goes through the graph, connecting all the
@ -88,6 +77,40 @@ func (g *Graph) ConnectDependents() {
} }
} }
// ConnectFrom creates an edge by finding the source from a DependableName
// and connecting it to the specific vertex.
func (g *Graph) ConnectFrom(source string, target dag.Vertex) {
g.once.Do(g.init)
if source := g.dependableMap[source]; source != nil {
g.Connect(dag.BasicEdge(source, target))
}
}
// ConnectTo connects a vertex to a raw string of targets that are the
// result of DependableName, and returns the list of targets that are missing.
func (g *Graph) ConnectTo(v dag.Vertex, targets []string) []string {
g.once.Do(g.init)
var missing []string
for _, t := range targets {
if dest := g.dependableMap[t]; dest != nil {
g.Connect(dag.BasicEdge(v, dest))
} else {
missing = append(missing, t)
}
}
return missing
}
// Dependable finds the vertices in the graph that have the given dependable
// names and returns them.
func (g *Graph) Dependable(n string) dag.Vertex {
// TODO: do we need this?
return nil
}
func (g *Graph) init() { func (g *Graph) init() {
if g.Graph == nil { if g.Graph == nil {
g.Graph = new(dag.Graph) g.Graph = new(dag.Graph)

View File

@ -28,14 +28,17 @@ func (t *TaintedTransformer) Transform(g *Graph) error {
} }
for i, _ := range rs.Tainted { for i, _ := range rs.Tainted {
g.Add(&graphNodeTaintedResource{ // Add the graph node and make the connection from any untainted
// resources with this name to the tainted resource, so that
// the tainted resource gets destroyed first.
g.ConnectFrom(k, g.Add(&graphNodeTaintedResource{
Index: i, Index: i,
ResourceName: k, ResourceName: k,
}) }))
} }
} }
// TODO: Dependencies? // TODO: Any other dependencies?
return nil return nil
} }
@ -46,14 +49,10 @@ type graphNodeTaintedResource struct {
ResourceName string ResourceName string
} }
func (n *graphNodeTaintedResource) DependableName() []string { func (n *graphNodeTaintedResource) DependentOn() []string {
return []string{n.dependableName()} return []string{n.ResourceName}
} }
func (n *graphNodeTaintedResource) Name() string { func (n *graphNodeTaintedResource) Name() string {
return fmt.Sprintf("%s (tainted #%d)", n.ResourceName, n.Index+1) return fmt.Sprintf("%s (tainted #%d)", n.ResourceName, n.Index+1)
} }
func (n *graphNodeTaintedResource) dependableName() string {
return n.ResourceName
}

View File

@ -45,5 +45,6 @@ func TestTaintedTransformer(t *testing.T) {
const testTransformTaintedBasicStr = ` const testTransformTaintedBasicStr = `
aws_instance.web aws_instance.web
aws_instance.web (tainted #1)
aws_instance.web (tainted #1) aws_instance.web (tainted #1)
` `