Merge pull request #22149 from hashicorp/jbardin/state-show-deposed
account for deposed in terraform show
This commit is contained in:
commit
8b2646c2a6
|
@ -98,78 +98,111 @@ 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))
|
||||
|
||||
var schema *configschema.Block
|
||||
provider := m.Resources[key].ProviderConfig.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
|
||||
// point. We can't return errors here, but since this is UI code
|
||||
// we will try to do _something_ reasonable.
|
||||
p.buf.WriteString(fmt.Sprintf("# missing schema for provider %q\n\n", provider))
|
||||
continue
|
||||
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})
|
||||
}
|
||||
|
||||
switch addr.Mode {
|
||||
case addrs.ManagedResourceMode:
|
||||
schema, _ = schemas.ResourceTypeConfig(
|
||||
provider,
|
||||
addr.Mode,
|
||||
addr.Type,
|
||||
)
|
||||
if schema == nil {
|
||||
p.buf.WriteString(fmt.Sprintf(
|
||||
"# missing schema for provider %q resource type %s\n\n", provider, addr.Type))
|
||||
// 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
|
||||
}
|
||||
|
||||
p.buf.WriteString(fmt.Sprintf(
|
||||
"resource %q %q {",
|
||||
addr.Type,
|
||||
addr.Name,
|
||||
))
|
||||
case addrs.DataResourceMode:
|
||||
schema, _ = schemas.ResourceTypeConfig(
|
||||
provider,
|
||||
addr.Mode,
|
||||
addr.Type,
|
||||
)
|
||||
if schema == nil {
|
||||
p.buf.WriteString(fmt.Sprintf(
|
||||
"# missing schema for provider %q data source %s\n\n", provider, addr.Type))
|
||||
var schema *configschema.Block
|
||||
provider := m.Resources[key].ProviderConfig.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
|
||||
// point. We can't return errors here, but since this is UI code
|
||||
// we will try to do _something_ reasonable.
|
||||
p.buf.WriteString(fmt.Sprintf("# missing schema for provider %q\n\n", provider))
|
||||
continue
|
||||
}
|
||||
|
||||
p.buf.WriteString(fmt.Sprintf(
|
||||
"data %q %q {",
|
||||
addr.Type,
|
||||
addr.Name,
|
||||
))
|
||||
default:
|
||||
// should never happen, since the above is exhaustive
|
||||
p.buf.WriteString(addr.String())
|
||||
}
|
||||
switch addr.Mode {
|
||||
case addrs.ManagedResourceMode:
|
||||
schema, _ = schemas.ResourceTypeConfig(
|
||||
provider,
|
||||
addr.Mode,
|
||||
addr.Type,
|
||||
)
|
||||
if schema == nil {
|
||||
p.buf.WriteString(fmt.Sprintf(
|
||||
"# missing schema for provider %q resource type %s\n\n", provider, addr.Type))
|
||||
continue
|
||||
}
|
||||
|
||||
val, err := v.Current.Decode(schema.ImpliedType())
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
break
|
||||
}
|
||||
p.buf.WriteString(fmt.Sprintf(
|
||||
"resource %q %q {",
|
||||
addr.Type,
|
||||
addr.Name,
|
||||
))
|
||||
case addrs.DataResourceMode:
|
||||
schema, _ = schemas.ResourceTypeConfig(
|
||||
provider,
|
||||
addr.Mode,
|
||||
addr.Type,
|
||||
)
|
||||
if schema == nil {
|
||||
p.buf.WriteString(fmt.Sprintf(
|
||||
"# missing schema for provider %q data source %s\n\n", provider, addr.Type))
|
||||
continue
|
||||
}
|
||||
|
||||
path := make(cty.Path, 0, 3)
|
||||
bodyWritten := p.writeBlockBodyDiff(schema, val.Value, val.Value, 2, path)
|
||||
if bodyWritten {
|
||||
p.buf.WriteString("\n")
|
||||
}
|
||||
p.buf.WriteString(fmt.Sprintf(
|
||||
"data %q %q {",
|
||||
addr.Type,
|
||||
addr.Name,
|
||||
))
|
||||
default:
|
||||
// should never happen, since the above is exhaustive
|
||||
p.buf.WriteString(addr.String())
|
||||
}
|
||||
|
||||
p.buf.WriteString("}\n\n")
|
||||
val, err := instance.Decode(schema.ImpliedType())
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
break
|
||||
}
|
||||
|
||||
path := make(cty.Path, 0, 3)
|
||||
bodyWritten := p.writeBlockBodyDiff(schema, val.Value, val.Value, 2, path)
|
||||
if bodyWritten {
|
||||
p.buf.WriteString("\n")
|
||||
}
|
||||
|
||||
p.buf.WriteString("}\n\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
p.buf.WriteString("\n")
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue