mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
terraform: deposed shows up in plan, tests
This commit is contained in:
parent
3bf93501a1
commit
6ee3a08799
@ -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")
|
||||
|
@ -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
|
||||
|
37
terraform/eval_diff_deposed.go
Normal file
37
terraform/eval_diff_deposed.go
Normal 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
|
||||
}
|
@ -177,6 +177,10 @@ func (n *NodePlannableResourceInstance) evalTreeManagedResource(
|
||||
OutputDiff: &diff,
|
||||
OutputState: &state,
|
||||
},
|
||||
&EvalDiffDeposed{
|
||||
Name: stateId,
|
||||
Diff: &diff,
|
||||
},
|
||||
&EvalCheckPreventDestroy{
|
||||
Resource: n.Config,
|
||||
Diff: &diff,
|
||||
|
3
terraform/test-fixtures/plan-cbd/main.tf
Normal file
3
terraform/test-fixtures/plan-cbd/main.tf
Normal file
@ -0,0 +1,3 @@
|
||||
resource "aws_instance" "foo" {
|
||||
lifecycle { create_before_destroy = true }
|
||||
}
|
Loading…
Reference in New Issue
Block a user