mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
backend/local: refresh with no config should not crash on input
Fixes #12174 You're allowed to refresh with a nil module (no configs) as long as you have state. However, if `-input=true` (default) then this would crash since the input attempts to read the configs. The API contract with `terraform.Context` says that the module tree must be non-nil and loaded. To do this for other commands we create an empty module tree. We do that here now.
This commit is contained in:
parent
d7da828866
commit
9574f16f92
@ -9,6 +9,7 @@ import (
|
|||||||
"github.com/hashicorp/go-multierror"
|
"github.com/hashicorp/go-multierror"
|
||||||
"github.com/hashicorp/terraform/backend"
|
"github.com/hashicorp/terraform/backend"
|
||||||
clistate "github.com/hashicorp/terraform/command/state"
|
clistate "github.com/hashicorp/terraform/command/state"
|
||||||
|
"github.com/hashicorp/terraform/config/module"
|
||||||
"github.com/hashicorp/terraform/state"
|
"github.com/hashicorp/terraform/state"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -42,6 +43,12 @@ func (b *Local) opRefresh(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we have no config module given to use, create an empty tree to
|
||||||
|
// avoid crashes when Terraform.Context is initialized.
|
||||||
|
if op.Module == nil {
|
||||||
|
op.Module = module.NewEmptyTree()
|
||||||
|
}
|
||||||
|
|
||||||
// Get our context
|
// Get our context
|
||||||
tfCtx, opState, err := b.context(op)
|
tfCtx, opState, err := b.context(op)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -40,6 +40,63 @@ test_instance.foo:
|
|||||||
`)
|
`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestLocal_refreshNilModule(t *testing.T) {
|
||||||
|
b := TestLocal(t)
|
||||||
|
p := TestLocalProvider(t, b, "test")
|
||||||
|
terraform.TestStateFile(t, b.StatePath, testRefreshState())
|
||||||
|
|
||||||
|
p.RefreshFn = nil
|
||||||
|
p.RefreshReturn = &terraform.InstanceState{ID: "yes"}
|
||||||
|
|
||||||
|
op := testOperationRefresh()
|
||||||
|
op.Module = nil
|
||||||
|
|
||||||
|
run, err := b.Operation(context.Background(), op)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("bad: %s", err)
|
||||||
|
}
|
||||||
|
<-run.Done()
|
||||||
|
|
||||||
|
if !p.RefreshCalled {
|
||||||
|
t.Fatal("refresh should be called")
|
||||||
|
}
|
||||||
|
|
||||||
|
checkState(t, b.StateOutPath, `
|
||||||
|
test_instance.foo:
|
||||||
|
ID = yes
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GH-12174
|
||||||
|
func TestLocal_refreshNilModuleWithInput(t *testing.T) {
|
||||||
|
b := TestLocal(t)
|
||||||
|
p := TestLocalProvider(t, b, "test")
|
||||||
|
terraform.TestStateFile(t, b.StatePath, testRefreshState())
|
||||||
|
|
||||||
|
p.RefreshFn = nil
|
||||||
|
p.RefreshReturn = &terraform.InstanceState{ID: "yes"}
|
||||||
|
|
||||||
|
b.OpInput = true
|
||||||
|
|
||||||
|
op := testOperationRefresh()
|
||||||
|
op.Module = nil
|
||||||
|
|
||||||
|
run, err := b.Operation(context.Background(), op)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("bad: %s", err)
|
||||||
|
}
|
||||||
|
<-run.Done()
|
||||||
|
|
||||||
|
if !p.RefreshCalled {
|
||||||
|
t.Fatal("refresh should be called")
|
||||||
|
}
|
||||||
|
|
||||||
|
checkState(t, b.StateOutPath, `
|
||||||
|
test_instance.foo:
|
||||||
|
ID = yes
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
|
||||||
func TestLocal_refreshInput(t *testing.T) {
|
func TestLocal_refreshInput(t *testing.T) {
|
||||||
b := TestLocal(t)
|
b := TestLocal(t)
|
||||||
p := TestLocalProvider(t, b, "test")
|
p := TestLocalProvider(t, b, "test")
|
||||||
|
Loading…
Reference in New Issue
Block a user