terraform: deposed shows up in plan, tests

This commit is contained in:
Mitchell Hashimoto 2016-11-28 13:35:29 -08:00
parent 3bf93501a1
commit 6ee3a08799
No known key found for this signature in database
GPG Key ID: 744E147AA52F5B0A
5 changed files with 121 additions and 5 deletions

View File

@ -38,6 +38,60 @@ func TestContext2Plan_basic(t *testing.T) {
}
}
func TestContext2Plan_createBefore_deposed(t *testing.T) {
m := testModule(t, "plan-cbd")
p := testProvider("aws")
p.DiffFn = testDiffFn
s := &State{
Modules: []*ModuleState{
&ModuleState{
Path: []string{"root"},
Resources: map[string]*ResourceState{
"aws_instance.foo": &ResourceState{
Type: "aws_instance",
Primary: &InstanceState{
ID: "baz",
},
Deposed: []*InstanceState{
&InstanceState{ID: "foo"},
},
},
},
},
},
}
ctx := testContext2(t, &ContextOpts{
Module: m,
Providers: map[string]ResourceProviderFactory{
"aws": testProviderFuncFixed(p),
},
State: s,
})
plan, err := ctx.Plan()
if err != nil {
t.Fatalf("err: %s", err)
}
actual := strings.TrimSpace(plan.String())
expected := strings.TrimSpace(`
DIFF:
DESTROY: aws_instance.foo (deposed only)
STATE:
aws_instance.foo: (1 deposed)
ID = baz
Deposed ID 1 = foo
`)
if actual != expected {
t.Fatalf("expected:\n%s, got:\n%s", expected, actual)
}
}
func TestContext2Plan_createBefore_maintainRoot(t *testing.T) {
m := testModule(t, "plan-cbd-maintain-root")
p := testProvider("aws")

View File

@ -291,16 +291,22 @@ func (d *ModuleDiff) String() string {
switch {
case rdiff.RequiresNew() && (rdiff.GetDestroy() || rdiff.GetDestroyTainted()):
crud = "DESTROY/CREATE"
case rdiff.GetDestroy():
case rdiff.GetDestroy() || rdiff.GetDestroyDeposed():
crud = "DESTROY"
case rdiff.RequiresNew():
crud = "CREATE"
}
extra := ""
if !rdiff.GetDestroy() && rdiff.GetDestroyDeposed() {
extra = " (deposed only)"
}
buf.WriteString(fmt.Sprintf(
"%s: %s\n",
"%s: %s%s\n",
crud,
name))
name,
extra))
keyLen := 0
rdiffAttrs := rdiff.CopyAttributes()
@ -356,6 +362,7 @@ type InstanceDiff struct {
mu sync.Mutex
Attributes map[string]*ResourceAttrDiff
Destroy bool
DestroyDeposed bool
DestroyTainted bool
}
@ -430,7 +437,7 @@ func (d *InstanceDiff) ChangeType() DiffChangeType {
return DiffDestroyCreate
}
if d.GetDestroy() {
if d.GetDestroy() || d.GetDestroyDeposed() {
return DiffDestroy
}
@ -449,7 +456,10 @@ func (d *InstanceDiff) Empty() bool {
d.mu.Lock()
defer d.mu.Unlock()
return !d.Destroy && !d.DestroyTainted && len(d.Attributes) == 0
return !d.Destroy &&
!d.DestroyTainted &&
!d.DestroyDeposed &&
len(d.Attributes) == 0
}
// Equal compares two diffs for exact equality.
@ -482,6 +492,7 @@ func (d *InstanceDiff) GoString() string {
Attributes: d.Attributes,
Destroy: d.Destroy,
DestroyTainted: d.DestroyTainted,
DestroyDeposed: d.DestroyDeposed,
})
}
@ -516,6 +527,13 @@ func (d *InstanceDiff) requiresNew() bool {
return false
}
func (d *InstanceDiff) GetDestroyDeposed() bool {
d.mu.Lock()
defer d.mu.Unlock()
return d.DestroyDeposed
}
// These methods are properly locked, for use outside other InstanceDiff
// methods but everywhere else within in the terraform package.
// TODO refactor the locking scheme

View File

@ -0,0 +1,37 @@
package terraform
// EvalDiffDeposed is an EvalNode implementation that marks DestroyDeposed
// in a diff if a resource has deposed instances that need destruction.
type EvalDiffDeposed struct {
Name string
Diff **InstanceDiff
}
// TODO: test
func (n *EvalDiffDeposed) Eval(ctx EvalContext) (interface{}, error) {
// Check if there are any deposed items in the state
deposed := false
_, err := readInstanceFromState(ctx, n.Name, nil, func(rs *ResourceState) (*InstanceState, error) {
if len(rs.Deposed) > 0 {
deposed = true
}
return nil, nil
})
if err != nil {
return nil, err
}
// If no deposed items, just return
if !deposed {
return nil, nil
}
// Set the flag to true
if *n.Diff == nil {
*n.Diff = new(InstanceDiff)
}
(*n.Diff).DestroyDeposed = true
return nil, nil
}

View File

@ -177,6 +177,10 @@ func (n *NodePlannableResourceInstance) evalTreeManagedResource(
OutputDiff: &diff,
OutputState: &state,
},
&EvalDiffDeposed{
Name: stateId,
Diff: &diff,
},
&EvalCheckPreventDestroy{
Resource: n.Config,
Diff: &diff,

View File

@ -0,0 +1,3 @@
resource "aws_instance" "foo" {
lifecycle { create_before_destroy = true }
}