mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-30 10:47:14 -06:00
terraform: validate diffs are the same
This commit is contained in:
parent
79eb52eba6
commit
d5e3d5a196
@ -485,14 +485,30 @@ func (c *Context) applyWalkFn() depgraph.WalkFunc {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// This should never happen because we check if Diff.Empty above.
|
||||
// If this happened, then the diff above returned a bad diff.
|
||||
if diff == nil {
|
||||
return fmt.Errorf(
|
||||
"%s: diff became nil during Apply. This is a bug with " +
|
||||
"the resource provider. Please report a bug.")
|
||||
// This should never happen because we check if Diff.Empty above.
|
||||
// If this happened, then the diff above returned a bad diff.
|
||||
if diff == nil {
|
||||
return fmt.Errorf(
|
||||
"%s: diff became nil during Apply. This is a bug with " +
|
||||
"the resource provider. Please report a bug.")
|
||||
}
|
||||
|
||||
// Delete id from the diff because it is dependent on
|
||||
// our internal plan function.
|
||||
delete(r.Diff.Attributes, "id")
|
||||
delete(diff.Attributes, "id")
|
||||
|
||||
// Verify the diffs are the same
|
||||
if !r.Diff.Same(diff) {
|
||||
log.Printf(
|
||||
"[ERROR] Diffs don't match.\n\nDiff 1: %#v"+
|
||||
"\n\nDiff 2: %#v",
|
||||
r.Diff, diff)
|
||||
return fmt.Errorf(
|
||||
"%s: diffs didn't match during apply. This is a " +
|
||||
"bug with the resource provider, please report a bug.")
|
||||
}
|
||||
}
|
||||
|
||||
// If we do not have any connection info, initialize
|
||||
|
@ -309,6 +309,35 @@ func TestContextApply_Minimal(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestContextApply_badDiff(t *testing.T) {
|
||||
c := testConfig(t, "apply-good")
|
||||
p := testProvider("aws")
|
||||
p.ApplyFn = testApplyFn
|
||||
p.DiffFn = testDiffFn
|
||||
ctx := testContext(t, &ContextOpts{
|
||||
Config: c,
|
||||
Providers: map[string]ResourceProviderFactory{
|
||||
"aws": testProviderFuncFixed(p),
|
||||
},
|
||||
})
|
||||
|
||||
if _, err := ctx.Plan(nil); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
p.DiffFn = func(*ResourceState, *ResourceConfig) (*ResourceDiff, error) {
|
||||
return &ResourceDiff{
|
||||
Attributes: map[string]*ResourceAttrDiff{
|
||||
"newp": nil,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
if _, err := ctx.Apply(); err == nil {
|
||||
t.Fatal("should error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestContextApply_cancel(t *testing.T) {
|
||||
stopped := false
|
||||
|
||||
|
@ -209,10 +209,40 @@ func (d *ResourceDiff) RequiresNew() bool {
|
||||
}
|
||||
|
||||
for _, rd := range d.Attributes {
|
||||
if rd.RequiresNew {
|
||||
if rd != nil && rd.RequiresNew {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// Same checks whether or not to ResourceDiffs are the "same." When
|
||||
// we say "same", it is not necessarily exactly equal. Instead, it is
|
||||
// just checking that the same attributes are changing, a destroy
|
||||
// isn't suddenly happening, etc.
|
||||
func (d *ResourceDiff) Same(d2 *ResourceDiff) bool {
|
||||
if d.Destroy != d2.Destroy {
|
||||
return false
|
||||
}
|
||||
if d.RequiresNew() != d2.RequiresNew() {
|
||||
return false
|
||||
}
|
||||
if len(d.Attributes) != len(d2.Attributes) {
|
||||
return false
|
||||
}
|
||||
|
||||
ks := make(map[string]struct{})
|
||||
for k, _ := range d.Attributes {
|
||||
ks[k] = struct{}{}
|
||||
}
|
||||
for k, _ := range d2.Attributes {
|
||||
delete(ks, k)
|
||||
}
|
||||
|
||||
if len(ks) > 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user