Merge pull request #22149 from hashicorp/jbardin/state-show-deposed

account for deposed in terraform show
This commit is contained in:
James Bardin 2019-07-29 14:25:02 -07:00 committed by GitHub
commit 8b2646c2a6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 207 additions and 55 deletions

View File

@ -98,13 +98,45 @@ func formatStateModule(p blockBodyDiffPrinter, m *states.Module, schemas *terraf
// Go through each resource and begin building up the output.
for _, key := range names {
for k, v := range m.Resources[key].Instances {
// keep these in order to keep the current object first, and
// provide deterministic output for the deposed objects
type obj struct {
header string
instance *states.ResourceInstanceObjectSrc
}
instances := []obj{}
addr := m.Resources[key].Addr
taintStr := ""
if v.Current.Status == 'T' {
if v.Current != nil && v.Current.Status == 'T' {
taintStr = " (tainted)"
}
p.buf.WriteString(fmt.Sprintf("# %s:%s\n", addr.Absolute(m.Addr).Instance(k), taintStr))
instances = append(instances,
obj{fmt.Sprintf("# %s:%s\n", addr.Absolute(m.Addr).Instance(k), taintStr), v.Current})
for dk, v := range v.Deposed {
instances = append(instances,
obj{fmt.Sprintf("# %s: (deposed object %s)\n", addr.Absolute(m.Addr).Instance(k), dk), v})
}
// Sort the instances for consistent output.
// Starting the sort from the second index, so the current instance
// is always first.
sort.Slice(instances[1:], func(i, j int) bool {
return instances[i+1].header < instances[j+1].header
})
for _, obj := range instances {
header := obj.header
instance := obj.instance
p.buf.WriteString(header)
if instance == nil {
// this shouldn't happen, but there's nothing to do here so
// don't panic below.
continue
}
var schema *configschema.Block
provider := m.Resources[key].ProviderConfig.ProviderConfig.StringCompact()
@ -157,7 +189,7 @@ func formatStateModule(p blockBodyDiffPrinter, m *states.Module, schemas *terraf
p.buf.WriteString(addr.String())
}
val, err := v.Current.Decode(schema.ImpliedType())
val, err := instance.Decode(schema.ImpliedType())
if err != nil {
fmt.Println(err.Error())
break
@ -172,6 +204,7 @@ func formatStateModule(p blockBodyDiffPrinter, m *states.Module, schemas *terraf
p.buf.WriteString("}\n\n")
}
}
}
p.buf.WriteString("\n")
}

View File

@ -47,6 +47,22 @@ func TestState(t *testing.T) {
},
nestedStateOutput,
},
{
&StateOpts{
State: deposedState(t),
Color: disabledColorize,
Schemas: testSchemas(),
},
deposedNestedStateOutput,
},
{
&StateOpts{
State: onlyDeposedState(t),
Color: disabledColorize,
Schemas: testSchemas(),
},
onlyDeposedOutput,
},
{
&StateOpts{
State: stateWithMoreOutputs(t),
@ -152,6 +168,43 @@ resource "test_resource" "baz" {
}
}`
const deposedNestedStateOutput = `# test_resource.baz[0]:
resource "test_resource" "baz" {
woozles = "confuzles"
nested {
value = "42"
}
}
# test_resource.baz[0]: (deposed object 1234)
resource "test_resource" "baz" {
woozles = "confuzles"
nested {
value = "42"
}
}`
const onlyDeposedOutput = `# test_resource.baz[0]:
# test_resource.baz[0]: (deposed object 1234)
resource "test_resource" "baz" {
woozles = "confuzles"
nested {
value = "42"
}
}
# test_resource.baz[0]: (deposed object 5678)
resource "test_resource" "baz" {
woozles = "confuzles"
nested {
value = "42"
}
}`
const stateWithMoreOutputsOutput = `# test_resource.baz[0]:
resource "test_resource" "baz" {
woozles = "confuzles"
@ -272,3 +325,69 @@ func nestedState(t *testing.T) *states.State {
)
return state
}
func deposedState(t *testing.T) *states.State {
state := nestedState(t)
rootModule := state.RootModule()
rootModule.SetResourceInstanceDeposed(
addrs.Resource{
Mode: addrs.ManagedResourceMode,
Type: "test_resource",
Name: "baz",
}.Instance(addrs.IntKey(0)),
states.DeposedKey("1234"),
&states.ResourceInstanceObjectSrc{
Status: states.ObjectReady,
SchemaVersion: 1,
AttrsJSON: []byte(`{"woozles":"confuzles","nested": [{"value": "42"}]}`),
},
addrs.ProviderConfig{
Type: "test",
}.Absolute(addrs.RootModuleInstance),
)
return state
}
// replicate a corrupt resource where only a deposed exists
func onlyDeposedState(t *testing.T) *states.State {
state := states.NewState()
rootModule := state.RootModule()
if rootModule == nil {
t.Errorf("root module is nil; want valid object")
}
rootModule.SetResourceInstanceDeposed(
addrs.Resource{
Mode: addrs.ManagedResourceMode,
Type: "test_resource",
Name: "baz",
}.Instance(addrs.IntKey(0)),
states.DeposedKey("1234"),
&states.ResourceInstanceObjectSrc{
Status: states.ObjectReady,
SchemaVersion: 1,
AttrsJSON: []byte(`{"woozles":"confuzles","nested": [{"value": "42"}]}`),
},
addrs.ProviderConfig{
Type: "test",
}.Absolute(addrs.RootModuleInstance),
)
rootModule.SetResourceInstanceDeposed(
addrs.Resource{
Mode: addrs.ManagedResourceMode,
Type: "test_resource",
Name: "baz",
}.Instance(addrs.IntKey(0)),
states.DeposedKey("5678"),
&states.ResourceInstanceObjectSrc{
Status: states.ObjectReady,
SchemaVersion: 1,
AttrsJSON: []byte(`{"woozles":"confuzles","nested": [{"value": "42"}]}`),
},
addrs.ProviderConfig{
Type: "test",
}.Absolute(addrs.RootModuleInstance),
)
return state
}