mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
Fix running tofu show
and tofu state show
with state files that reference Terraform registry providers. (#1141)
Signed-off-by: Jakub Martin <kubam@spacelift.io>
This commit is contained in:
parent
3bc81f29a9
commit
9f95a840b0
@ -22,6 +22,7 @@ import (
|
||||
"github.com/opentofu/opentofu/internal/states/statemgr"
|
||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||
"github.com/opentofu/opentofu/internal/tofu"
|
||||
"github.com/opentofu/opentofu/internal/tofumigrate"
|
||||
)
|
||||
|
||||
// Many of the methods we get data from can emit special error types if they're
|
||||
@ -108,7 +109,7 @@ func (c *ShowCommand) Synopsis() string {
|
||||
}
|
||||
|
||||
func (c *ShowCommand) show(path string) (*plans.Plan, *cloudplan.RemotePlanJSON, *statefile.File, *configs.Config, *tofu.Schemas, tfdiags.Diagnostics) {
|
||||
var diags, showDiags tfdiags.Diagnostics
|
||||
var diags, showDiags, migrateDiags tfdiags.Diagnostics
|
||||
var plan *plans.Plan
|
||||
var jsonPlan *cloudplan.RemotePlanJSON
|
||||
var stateFile *statefile.File
|
||||
@ -136,6 +137,14 @@ func (c *ShowCommand) show(path string) (*plans.Plan, *cloudplan.RemotePlanJSON,
|
||||
}
|
||||
}
|
||||
|
||||
if stateFile != nil {
|
||||
stateFile.State, migrateDiags = tofumigrate.MigrateStateProviderAddresses(config, stateFile.State)
|
||||
diags = diags.Append(migrateDiags)
|
||||
if migrateDiags.HasErrors() {
|
||||
return plan, jsonPlan, stateFile, config, schemas, diags
|
||||
}
|
||||
}
|
||||
|
||||
// Get schemas, if possible
|
||||
if config != nil || stateFile != nil {
|
||||
schemas, diags = c.MaybeGetSchemas(stateFile.State, config)
|
||||
|
@ -18,6 +18,7 @@ import (
|
||||
"github.com/opentofu/opentofu/internal/command/jsonstate"
|
||||
"github.com/opentofu/opentofu/internal/states"
|
||||
"github.com/opentofu/opentofu/internal/states/statefile"
|
||||
"github.com/opentofu/opentofu/internal/tofumigrate"
|
||||
)
|
||||
|
||||
// StateShowCommand is a Command implementation that shows a single resource.
|
||||
@ -124,6 +125,13 @@ func (c *StateShowCommand) Run(args []string) int {
|
||||
c.Streams.Eprintln(errStateNotFound)
|
||||
return 1
|
||||
}
|
||||
migratedState, migrateDiags := tofumigrate.MigrateStateProviderAddresses(lr.Config, state)
|
||||
diags = diags.Append(migrateDiags)
|
||||
if migrateDiags.HasErrors() {
|
||||
c.View.Diagnostics(diags)
|
||||
return 1
|
||||
}
|
||||
state = migratedState
|
||||
|
||||
is := state.ResourceInstance(addr)
|
||||
if !is.HasCurrent() {
|
||||
|
@ -3,9 +3,11 @@ package tofumigrate
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
tfaddr "github.com/opentofu/registry-address"
|
||||
|
||||
"github.com/opentofu/opentofu/internal/configs"
|
||||
"github.com/opentofu/opentofu/internal/getproviders"
|
||||
"github.com/opentofu/opentofu/internal/states"
|
||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||
)
|
||||
@ -37,14 +39,23 @@ func MigrateStateProviderAddresses(config *configs.Config, state *states.State)
|
||||
return state, nil
|
||||
}
|
||||
|
||||
if state == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var diags tfdiags.Diagnostics
|
||||
|
||||
stateCopy := state.DeepCopy()
|
||||
|
||||
providers, hclDiags := config.ProviderRequirements()
|
||||
diags = diags.Append(hclDiags)
|
||||
if hclDiags.HasErrors() {
|
||||
return nil, diags
|
||||
providers := getproviders.Requirements{}
|
||||
// config could be nil when we're e.g. showing a statefile without the configuration present
|
||||
if config != nil {
|
||||
var hclDiags hcl.Diagnostics
|
||||
providers, hclDiags = config.ProviderRequirements()
|
||||
diags = diags.Append(hclDiags)
|
||||
if hclDiags.HasErrors() {
|
||||
return nil, diags
|
||||
}
|
||||
}
|
||||
|
||||
for _, module := range stateCopy.Modules {
|
||||
|
@ -4,7 +4,10 @@ import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
|
||||
"github.com/opentofu/opentofu/internal/addrs"
|
||||
"github.com/opentofu/opentofu/internal/configs"
|
||||
"github.com/opentofu/opentofu/internal/configs/configload"
|
||||
"github.com/opentofu/opentofu/internal/states"
|
||||
)
|
||||
@ -163,12 +166,58 @@ func TestMigrateStateProviderAddresses(t *testing.T) {
|
||||
)
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "if there is no code, migrate",
|
||||
args: args{
|
||||
configDir: "",
|
||||
state: states.BuildState(func(s *states.SyncState) {
|
||||
s.SetResourceInstanceCurrent(
|
||||
mustParseInstAddr("random_id.example"),
|
||||
&states.ResourceInstanceObjectSrc{
|
||||
Status: states.ObjectReady,
|
||||
AttrsJSON: []byte(`{}`),
|
||||
},
|
||||
makeRootProviderAddr("registry.terraform.io/hashicorp/random"),
|
||||
)
|
||||
s.SetResourceInstanceCurrent(
|
||||
mustParseInstAddr("aws_instance.example"),
|
||||
&states.ResourceInstanceObjectSrc{
|
||||
Status: states.ObjectReady,
|
||||
AttrsJSON: []byte(`{}`),
|
||||
},
|
||||
makeRootProviderAddr("registry.terraform.io/hashicorp/aws"),
|
||||
)
|
||||
}),
|
||||
},
|
||||
want: states.BuildState(func(s *states.SyncState) {
|
||||
s.SetResourceInstanceCurrent(
|
||||
mustParseInstAddr("random_id.example"),
|
||||
&states.ResourceInstanceObjectSrc{
|
||||
Status: states.ObjectReady,
|
||||
AttrsJSON: []byte(`{}`),
|
||||
},
|
||||
makeRootProviderAddr("registry.opentofu.org/hashicorp/random"),
|
||||
)
|
||||
s.SetResourceInstanceCurrent(
|
||||
mustParseInstAddr("aws_instance.example"),
|
||||
&states.ResourceInstanceObjectSrc{
|
||||
Status: states.ObjectReady,
|
||||
AttrsJSON: []byte(`{}`),
|
||||
},
|
||||
makeRootProviderAddr("registry.opentofu.org/hashicorp/aws"),
|
||||
)
|
||||
}),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
cfg, hclDiags := loader.LoadConfig(tt.args.configDir)
|
||||
if hclDiags.HasErrors() {
|
||||
t.Fatalf("invalid configuration: %s", hclDiags.Error())
|
||||
var cfg *configs.Config
|
||||
if tt.args.configDir != "" {
|
||||
var hclDiags hcl.Diagnostics
|
||||
cfg, hclDiags = loader.LoadConfig(tt.args.configDir)
|
||||
if hclDiags.HasErrors() {
|
||||
t.Fatalf("invalid configuration: %s", hclDiags.Error())
|
||||
}
|
||||
}
|
||||
|
||||
got, err := MigrateStateProviderAddresses(cfg, tt.args.state)
|
||||
|
Loading…
Reference in New Issue
Block a user