terraform: refresh tainted resources

This commit is contained in:
Mitchell Hashimoto 2015-02-11 14:14:05 -08:00
parent e5e4ac7548
commit 2680b6bed4
4 changed files with 61 additions and 12 deletions

View File

@ -365,8 +365,7 @@ func TestContext2Refresh_state(t *testing.T) {
}
}
/*
func TestContextRefresh_tainted(t *testing.T) {
func TestContext2Refresh_tainted(t *testing.T) {
p := testProvider("aws")
m := testModule(t, "refresh-basic")
state := &State{
@ -386,7 +385,7 @@ func TestContextRefresh_tainted(t *testing.T) {
},
},
}
ctx := testContext(t, &ContextOpts{
ctx := testContext2(t, &ContextOpts{
Module: m,
Providers: map[string]ResourceProviderFactory{
"aws": testProviderFuncFixed(p),
@ -414,6 +413,7 @@ func TestContextRefresh_tainted(t *testing.T) {
}
}
/*
func TestContextRefresh_vars(t *testing.T) {
p := testProvider("aws")
m := testModule(t, "refresh-vars")

View File

@ -7,7 +7,9 @@ import (
// EvalReadState is an EvalNode implementation that reads the
// InstanceState for a specific resource out of the state.
type EvalReadState struct {
Name string
Name string
Tainted bool
TaintedIndex int
}
func (n *EvalReadState) Args() ([]EvalNode, []EvalType) {
@ -35,8 +37,13 @@ func (n *EvalReadState) Eval(
return nil, nil
}
// Return the primary
return rs.Primary, nil
if !n.Tainted {
// Return the primary
return rs.Primary, nil
} else {
// Return the proper tainted resource
return rs.Tainted[n.TaintedIndex], nil
}
}
func (n *EvalReadState) Type() EvalType {
@ -50,6 +57,8 @@ type EvalWriteState struct {
ResourceType string
Dependencies []string
State EvalNode
Tainted bool
TaintedIndex int
}
func (n *EvalWriteState) Args() ([]EvalNode, []EvalType) {
@ -89,8 +98,14 @@ func (n *EvalWriteState) Eval(
rs.Type = n.ResourceType
rs.Dependencies = n.Dependencies
// Set the primary state
rs.Primary = instanceState
if n.Tainted {
if n.TaintedIndex != -1 {
rs.Tainted[n.TaintedIndex] = instanceState
}
} else {
// Set the primary state
rs.Primary = instanceState
}
// Prune because why not, we can clear out old useless entries now
rs.prune()

View File

@ -72,8 +72,8 @@ func (n *graphNodeExpandedResource) DependentOn() []string {
}
// GraphNodeProviderConsumer
func (n *graphNodeExpandedResource) ProvidedBy() string {
return resourceProvider(n.Resource.Type)
func (n *graphNodeExpandedResource) ProvidedBy() []string {
return []string{resourceProvider(n.Resource.Type)}
}
// GraphNodeEvalable impl.
@ -82,7 +82,7 @@ func (n *graphNodeExpandedResource) EvalTree() EvalNode {
// Validate the resource
seq.Nodes = append(seq.Nodes, &EvalValidateResource{
Provider: &EvalGetProvider{Name: n.ProvidedBy()},
Provider: &EvalGetProvider{Name: n.ProvidedBy()[0]},
Config: &EvalInterpolate{Config: n.Resource.RawConfig},
ResourceName: n.Resource.Name,
ResourceType: n.Resource.Type,
@ -109,7 +109,7 @@ func (n *graphNodeExpandedResource) EvalTree() EvalNode {
Dependencies: n.DependentOn(),
State: &EvalRefresh{
Info: info,
Provider: &EvalGetProvider{Name: n.ProvidedBy()},
Provider: &EvalGetProvider{Name: n.ProvidedBy()[0]},
State: &EvalReadState{Name: n.stateId()},
},
},

View File

@ -34,6 +34,7 @@ func (t *TaintedTransformer) Transform(g *Graph) error {
g.ConnectFrom(k, g.Add(&graphNodeTaintedResource{
Index: i,
ResourceName: k,
ResourceType: rs.Type,
}))
}
}
@ -47,6 +48,7 @@ func (t *TaintedTransformer) Transform(g *Graph) error {
type graphNodeTaintedResource struct {
Index int
ResourceName string
ResourceType string
}
func (n *graphNodeTaintedResource) DependentOn() []string {
@ -60,3 +62,35 @@ func (n *graphNodeTaintedResource) Name() string {
func (n *graphNodeTaintedResource) ProvidedBy() []string {
return []string{resourceProvider(n.ResourceName)}
}
// GraphNodeEvalable impl.
func (n *graphNodeTaintedResource) EvalTree() EvalNode {
seq := &EvalSequence{Nodes: make([]EvalNode, 0, 5)}
// Build instance info
info := &InstanceInfo{Id: n.ResourceName, Type: n.ResourceType}
seq.Nodes = append(seq.Nodes, &EvalInstanceInfo{Info: info})
// Refresh the resource
seq.Nodes = append(seq.Nodes, &EvalOpFilter{
Ops: []walkOperation{walkRefresh},
Node: &EvalWriteState{
Name: n.ResourceName,
ResourceType: n.ResourceType,
Dependencies: n.DependentOn(),
Tainted: true,
TaintedIndex: n.Index,
State: &EvalRefresh{
Info: info,
Provider: &EvalGetProvider{Name: n.ProvidedBy()[0]},
State: &EvalReadState{
Name: n.ResourceName,
Tainted: true,
TaintedIndex: n.Index,
},
},
},
})
return seq
}