mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
Skip imports on tofu destroy
(#2214)
Signed-off-by: Ronny Orot <ronny.orot@gmail.com>
This commit is contained in:
parent
5d48a940da
commit
cf34b0e6a9
@ -60,6 +60,7 @@ BUG FIXES:
|
||||
* A `module` block's `version` argument now accepts prerelease version selections using a "v" prefix before the version number. Previously this was accepted only for non-prerelease selections. ([#2124])(https://github.com/opentofu/opentofu/issues/2124)
|
||||
* The `tofu test` command doesn't try to validate mock provider definition by its underlying provider schema now. ([#2140](https://github.com/opentofu/opentofu/pull/2140))
|
||||
* Type validation for mocks and overrides are now less strict in `tofu test`. ([#2144](https://github.com/opentofu/opentofu/pull/2144))
|
||||
* Skip imports blocks logic on `tofu destroy` ([#2214](https://github.com/opentofu/opentofu/pull/2214))
|
||||
|
||||
INTERNAL CHANGES:
|
||||
|
||||
|
@ -1046,6 +1046,80 @@ resource "test_object" "a" {
|
||||
}
|
||||
}
|
||||
|
||||
func TestContext2Plan_destroyWithRefresh_skipImport(t *testing.T) {
|
||||
m := testModuleInline(t, map[string]string{
|
||||
"main.tf": `
|
||||
resource "test_object" "a" {
|
||||
}
|
||||
|
||||
resource "test_object" "imported" {
|
||||
}
|
||||
|
||||
import {
|
||||
to = test_object.imported
|
||||
id = "123"
|
||||
}
|
||||
`,
|
||||
})
|
||||
|
||||
p := simpleMockProvider()
|
||||
|
||||
p.ReadResourceResponse = &providers.ReadResourceResponse{
|
||||
NewState: cty.ObjectVal(map[string]cty.Value{
|
||||
"test_string": cty.StringVal("foo"),
|
||||
}),
|
||||
}
|
||||
|
||||
p.ImportResourceStateResponse = &providers.ImportResourceStateResponse{
|
||||
ImportedResources: []providers.ImportedResource{
|
||||
{
|
||||
TypeName: "test_object",
|
||||
State: cty.ObjectVal(map[string]cty.Value{
|
||||
"test_string": cty.StringVal("foo"),
|
||||
}),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
expectedDestroyedAddr := mustResourceInstanceAddr("test_object.a")
|
||||
state := states.BuildState(func(s *states.SyncState) {
|
||||
s.SetResourceInstanceCurrent(expectedDestroyedAddr, &states.ResourceInstanceObjectSrc{
|
||||
AttrsJSON: []byte(`{"arg":"before"}`),
|
||||
Status: states.ObjectReady,
|
||||
}, mustProviderConfig(`provider["registry.opentofu.org/hashicorp/test"]`), addrs.NoKey)
|
||||
})
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, state, &PlanOpts{
|
||||
Mode: plans.DestroyMode,
|
||||
SkipRefresh: false, // the default
|
||||
})
|
||||
assertNoErrors(t, diags)
|
||||
|
||||
if plan.PriorState == nil {
|
||||
t.Fatal("missing plan state")
|
||||
}
|
||||
|
||||
if len(plan.Changes.Resources) > 1 {
|
||||
t.Fatal("only a single resource should be changed in the plan")
|
||||
}
|
||||
|
||||
changedResource := plan.Changes.Resources[0]
|
||||
|
||||
if changedResource.Action != plans.Delete {
|
||||
t.Errorf("unexpected %s change for %s", changedResource.Action, changedResource.Addr)
|
||||
}
|
||||
|
||||
if !changedResource.Addr.Equal(expectedDestroyedAddr) {
|
||||
t.Errorf("unexpected change for resource %s instead of %s", changedResource.Addr, expectedDestroyedAddr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestContext2Plan_destroySkipRefresh(t *testing.T) {
|
||||
m := testModuleInline(t, map[string]string{
|
||||
"main.tf": `
|
||||
|
@ -156,7 +156,12 @@ func (n *nodeExpandPlannableResource) DynamicExpand(ctx EvalContext) (*Graph, er
|
||||
importResolver := ctx.ImportResolver()
|
||||
var diags tfdiags.Diagnostics
|
||||
for _, importTarget := range n.importTargets {
|
||||
if importTarget.IsFromImportBlock() {
|
||||
// If the import target originates from the import command (instead of the import block), we don't need to
|
||||
// resolve the import as it's already in the resolved form
|
||||
// In addition, if PreDestroyRefresh is true, we know we are running as part of a refresh plan, immediately before a destroy
|
||||
// plan. In the destroy plan mode, import blocks are not relevant, that's why we skip resolving imports
|
||||
skipImports := importTarget.IsFromImportBlock() && !n.preDestroyRefresh
|
||||
if skipImports {
|
||||
err := importResolver.ExpandAndResolveImport(importTarget, ctx)
|
||||
diags = diags.Append(err)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user