Skip to content

Commit

Permalink
command/show: fix issue with show and aliased provider (#23848)
Browse files Browse the repository at this point in the history
The formatter in `command/format/state.go`, when formatting a resource
with an aliased provider, was looking for a schema with the alias (ie,
test.foo), but the schemas are only listed by provider type (test).
Update the state formatter to lookup schemas by provider type only.

Some of the show tests (and a couple others) were not properly cleaning
up the created tmpdirs, so I fixed those. Also, the show tests are using
a statefile named `state.tfstate`, but were not passing that path to the
show command, so we were getting some false positives (a `show` command
that returns `no state` exits 0).

Fixes #21462
  • Loading branch information
mildwonkey authored Jan 13, 2020
1 parent 272cb44 commit 92f4277
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 5 deletions.
2 changes: 1 addition & 1 deletion command/format/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ func formatStateModule(p blockBodyDiffPrinter, m *states.Module, schemas *terraf
}

var schema *configschema.Block
provider := m.Resources[key].ProviderConfig.ProviderConfig.StringCompact()
provider := addr.DefaultProviderConfig().Absolute(m.Addr).ProviderConfig.StringCompact()
if _, exists := schemas.Providers[provider]; !exists {
// This should never happen in normal use because we should've
// loaded all of the schemas and checked things prior to this
Expand Down
1 change: 1 addition & 0 deletions command/init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1237,6 +1237,7 @@ func TestInit_providerLockFile(t *testing.T) {

func TestInit_pluginDirReset(t *testing.T) {
td := testTempDir(t)
defer os.RemoveAll(td)
defer testChdir(t, td)()

ui := new(cli.MockUi)
Expand Down
1 change: 1 addition & 0 deletions command/plugins_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ func TestMultiVersionProviderResolver(t *testing.T) {

func TestPluginPath(t *testing.T) {
td := testTempDir(t)
defer os.RemoveAll(td)
defer testChdir(t, td)()

pluginPath := []string{"a", "b", "c"}
Expand Down
70 changes: 66 additions & 4 deletions command/show_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package command

import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"path/filepath"
Expand Down Expand Up @@ -41,7 +42,9 @@ func TestShow(t *testing.T) {
func TestShow_noArgs(t *testing.T) {
// Create the default state
statePath := testStateFile(t, testState())
defer testChdir(t, filepath.Dir(statePath))()
stateDir := filepath.Dir(statePath)
defer os.RemoveAll(stateDir)
defer testChdir(t, stateDir)()

ui := new(cli.MockUi)
c := &ShowCommand{
Expand All @@ -51,16 +54,73 @@ func TestShow_noArgs(t *testing.T) {
},
}

args := []string{}
// the statefile created by testStateFile is named state.tfstate
// so one arg is required
args := []string{"state.tfstate"}
if code := c.Run(args); code != 0 {
t.Fatalf("bad: \n%s", ui.OutputWriter.String())
}

if !strings.Contains(ui.OutputWriter.String(), "# test_instance.foo:") {
t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
}
}

// https://github.com/hashicorp/terraform/issues/21462
func TestShow_aliasedProvider(t *testing.T) {
// Create the default state with aliased resource
testState := states.BuildState(func(s *states.SyncState) {
s.SetResourceInstanceCurrent(
addrs.Resource{
Mode: addrs.ManagedResourceMode,
Type: "test_instance",
Name: "foo",
}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance),
&states.ResourceInstanceObjectSrc{
// The weird whitespace here is reflective of how this would
// get written out in a real state file, due to the indentation
// of all of the containing wrapping objects and arrays.
AttrsJSON: []byte("{\n \"id\": \"bar\"\n }"),
Status: states.ObjectReady,
Dependencies: []addrs.AbsResource{},
DependsOn: []addrs.Referenceable{},
},
addrs.RootModuleInstance.ProviderConfigAliased("test", "alias"),
)
})

statePath := testStateFile(t, testState)
stateDir := filepath.Dir(statePath)
defer os.RemoveAll(stateDir)
defer testChdir(t, stateDir)()

ui := new(cli.MockUi)
c := &ShowCommand{
Meta: Meta{
testingOverrides: metaOverridesForProvider(testProvider()),
Ui: ui,
},
}

fmt.Println(os.Getwd())

// the statefile created by testStateFile is named state.tfstate
args := []string{"state.tfstate"}
if code := c.Run(args); code != 0 {
t.Fatalf("bad exit code: \n%s", ui.OutputWriter.String())
}

if strings.Contains(ui.OutputWriter.String(), "# missing schema for provider \"test.alias\"") {
t.Fatalf("bad output: \n%s", ui.OutputWriter.String())
}
}

func TestShow_noArgsNoState(t *testing.T) {
// Create the default state
statePath := testStateFile(t, testState())
defer testChdir(t, filepath.Dir(statePath))()
stateDir := filepath.Dir(statePath)
defer os.RemoveAll(stateDir)
defer testChdir(t, stateDir)()

ui := new(cli.MockUi)
c := &ShowCommand{
Expand All @@ -70,7 +130,8 @@ func TestShow_noArgsNoState(t *testing.T) {
},
}

args := []string{}
// the statefile created by testStateFile is named state.tfstate
args := []string{"state.tfstate"}
if code := c.Run(args); code != 0 {
t.Fatalf("bad: \n%s", ui.OutputWriter.String())
}
Expand Down Expand Up @@ -150,6 +211,7 @@ func TestShow_plan_json(t *testing.T) {
func TestShow_state(t *testing.T) {
originalState := testState()
statePath := testStateFile(t, originalState)
defer os.RemoveAll(filepath.Dir(statePath))

ui := new(cli.MockUi)
c := &ShowCommand{
Expand Down

0 comments on commit 92f4277

Please # to comment.