Account for deposed instances in show command, adding the details for
each deposed instance. Prevent crash if the current instance is missing.
This commit is contained in:
parent
b117457c6a
commit
345dfaccb6
|
@ -98,13 +98,45 @@ func formatStateModule(p blockBodyDiffPrinter, m *states.Module, schemas *terraf
|
||||||
// Go through each resource and begin building up the output.
|
// Go through each resource and begin building up the output.
|
||||||
for _, key := range names {
|
for _, key := range names {
|
||||||
for k, v := range m.Resources[key].Instances {
|
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
|
addr := m.Resources[key].Addr
|
||||||
|
|
||||||
taintStr := ""
|
taintStr := ""
|
||||||
if v.Current.Status == 'T' {
|
if v.Current != nil && v.Current.Status == 'T' {
|
||||||
taintStr = " (tainted)"
|
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
|
var schema *configschema.Block
|
||||||
provider := m.Resources[key].ProviderConfig.ProviderConfig.StringCompact()
|
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())
|
p.buf.WriteString(addr.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
val, err := v.Current.Decode(schema.ImpliedType())
|
val, err := instance.Decode(schema.ImpliedType())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err.Error())
|
fmt.Println(err.Error())
|
||||||
break
|
break
|
||||||
|
@ -172,6 +204,7 @@ func formatStateModule(p blockBodyDiffPrinter, m *states.Module, schemas *terraf
|
||||||
p.buf.WriteString("}\n\n")
|
p.buf.WriteString("}\n\n")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
p.buf.WriteString("\n")
|
p.buf.WriteString("\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,22 @@ func TestState(t *testing.T) {
|
||||||
},
|
},
|
||||||
nestedStateOutput,
|
nestedStateOutput,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
&StateOpts{
|
||||||
|
State: deposedState(t),
|
||||||
|
Color: disabledColorize,
|
||||||
|
Schemas: testSchemas(),
|
||||||
|
},
|
||||||
|
deposedNestedStateOutput,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
&StateOpts{
|
||||||
|
State: onlyDeposedState(t),
|
||||||
|
Color: disabledColorize,
|
||||||
|
Schemas: testSchemas(),
|
||||||
|
},
|
||||||
|
onlyDeposedOutput,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
&StateOpts{
|
&StateOpts{
|
||||||
State: stateWithMoreOutputs(t),
|
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]:
|
const stateWithMoreOutputsOutput = `# test_resource.baz[0]:
|
||||||
resource "test_resource" "baz" {
|
resource "test_resource" "baz" {
|
||||||
woozles = "confuzles"
|
woozles = "confuzles"
|
||||||
|
@ -272,3 +325,69 @@ func nestedState(t *testing.T) *states.State {
|
||||||
)
|
)
|
||||||
return 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
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue