|
|
|
|
@ -606,13 +606,36 @@ func (d *InstanceDiff) Same(d2 *InstanceDiff) (bool, string) {
|
|
|
|
|
d.mu.Lock()
|
|
|
|
|
defer d.mu.Unlock()
|
|
|
|
|
|
|
|
|
|
if d.Destroy != d2.GetDestroy() {
|
|
|
|
|
// If we're going from requiring new to NOT requiring new, then we have
|
|
|
|
|
// to see if all required news were computed. If so, it is allowed since
|
|
|
|
|
// computed may also mean "same value and therefore not new".
|
|
|
|
|
oldNew := d.requiresNew()
|
|
|
|
|
newNew := d2.RequiresNew()
|
|
|
|
|
if oldNew && !newNew {
|
|
|
|
|
oldNew = false
|
|
|
|
|
for _, rd := range d.Attributes {
|
|
|
|
|
// If the field is requires new and NOT computed, then what
|
|
|
|
|
// we have is a diff mismatch for sure. We set that the old
|
|
|
|
|
// diff does REQUIRE a ForceNew.
|
|
|
|
|
if rd != nil && rd.RequiresNew && !rd.NewComputed {
|
|
|
|
|
oldNew = true
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if oldNew != newNew {
|
|
|
|
|
return false, fmt.Sprintf(
|
|
|
|
|
"diff: Destroy; old: %t, new: %t", d.Destroy, d2.GetDestroy())
|
|
|
|
|
"diff RequiresNew; old: %t, new: %t", oldNew, newNew)
|
|
|
|
|
}
|
|
|
|
|
if d.requiresNew() != d2.RequiresNew() {
|
|
|
|
|
|
|
|
|
|
// Verify that destroy matches. The second boolean here allows us to
|
|
|
|
|
// have mismatching Destroy if we're moving from RequiresNew true
|
|
|
|
|
// to false above. Therefore, the second boolean will only pass if
|
|
|
|
|
// we're moving from Destroy: true to false as well.
|
|
|
|
|
if d.Destroy != d2.GetDestroy() && d.requiresNew() == oldNew {
|
|
|
|
|
return false, fmt.Sprintf(
|
|
|
|
|
"diff RequiresNew; old: %t, new: %t", d.requiresNew(), d2.RequiresNew())
|
|
|
|
|
"diff: Destroy; old: %t, new: %t", d.Destroy, d2.GetDestroy())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Go through the old diff and make sure the new diff has all the
|
|
|
|
|
|