command/format: include nested blocks in `terraform show` output (#20149)

* command/format: include nested blocks in terraform show output
* command/format: fix tests
This commit is contained in:
Kristin Laemmert 2019-01-30 10:08:59 -08:00 committed by GitHub
parent 477da57a92
commit 653bb74403
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 65 additions and 18 deletions

View File

@ -6,6 +6,8 @@ import (
"sort"
"strings"
"github.com/zclconf/go-cty/cty"
"github.com/hashicorp/terraform/addrs"
"github.com/hashicorp/terraform/configs/configschema"
"github.com/hashicorp/terraform/plans"
@ -121,7 +123,7 @@ func formatStateModule(p blockBodyDiffPrinter, m *states.Module, schemas *terraf
}
p.buf.WriteString(fmt.Sprintf(
"resource %q %q {\n",
"resource %q %q {",
addr.Type,
addr.Name,
))
@ -134,7 +136,7 @@ func formatStateModule(p blockBodyDiffPrinter, m *states.Module, schemas *terraf
}
p.buf.WriteString(fmt.Sprintf(
"data %q %q {\n",
"data %q %q {",
addr.Type,
addr.Name,
))
@ -150,23 +152,12 @@ func formatStateModule(p blockBodyDiffPrinter, m *states.Module, schemas *terraf
break
}
// First get the names of all the attributes so we can show them
// in alphabetical order.
names := make([]string, 0, len(schema.Attributes))
for name := range schema.Attributes {
names = append(names, name)
}
sort.Strings(names)
for _, name := range names {
attr := ctyGetAttrMaybeNull(val.Value, name)
if !attr.IsNull() {
p.buf.WriteString(fmt.Sprintf(" %s = ", name))
attr := ctyGetAttrMaybeNull(val.Value, name)
p.writeValue(attr, plans.NoOp, 4)
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")
}
}

View File

@ -63,6 +63,14 @@ func TestState(t *testing.T) {
},
TestOutput,
},
{
&StateOpts{
State: nestedState(t),
Color: disabledColorize,
Schemas: testSchemas(),
},
nestedTestOutput,
},
}
for _, tt := range tests {
@ -101,6 +109,17 @@ func testProviderSchema() *terraform.ProviderSchema {
"foo": {Type: cty.String, Optional: true},
"woozles": {Type: cty.String, Optional: true},
},
BlockTypes: map[string]*configschema.NestedBlock{
"nested": {
Nesting: configschema.NestingList,
Block: configschema.Block{
Attributes: map[string]*configschema.Attribute{
"compute": {Type: cty.String, Optional: true},
"value": {Type: cty.String, Optional: true},
},
},
},
},
},
},
DataSources: map[string]*configschema.Block{
@ -132,3 +151,40 @@ resource "test_resource" "baz" {
Outputs:
bar = "bar value"`
const nestedTestOutput = `# test_resource.baz[0]:
resource "test_resource" "baz" {
woozles = "confuzles"
nested {
value = "42"
}
}
`
func nestedState(t *testing.T) *states.State {
state := states.NewState()
rootModule := state.RootModule()
if rootModule == nil {
t.Errorf("root module is nil; want valid object")
}
rootModule.SetResourceInstanceCurrent(
addrs.Resource{
Mode: addrs.ManagedResourceMode,
Type: "test_resource",
Name: "baz",
}.Instance(addrs.IntKey(0)),
&states.ResourceInstanceObjectSrc{
Status: states.ObjectReady,
SchemaVersion: 1,
AttrsJSON: []byte(`{"woozles":"confuzles","nested": [{"value": "42"}]}`),
},
addrs.ProviderConfig{
Type: "test",
}.Absolute(addrs.RootModuleInstance),
)
return state
}