From c810e4582c9d98174c8eb784c3ad451e99dd9d14 Mon Sep 17 00:00:00 2001 From: Kristin Laemmert Date: Fri, 1 Feb 2019 13:47:18 -0800 Subject: [PATCH] command/show: continued work on `terraform show -json` output (#20171) * command/jsonstate: do not hide SchemaVersion of '0' * command/jsonconfig: module_calls should be a map * command/jsonplan: include current terraform version in output * command/jsonconfig: properly marshal expressions from a module call Previously this was looking at the root module's variables, instead of the child module variables, to build the module schema. This fixes that bug. --- command/jsonconfig/config.go | 34 ++++++++++++++++++---------------- command/jsonplan/plan.go | 7 +++++-- command/jsonstate/state.go | 2 +- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/command/jsonconfig/config.go b/command/jsonconfig/config.go index 47731149f..8a5285788 100644 --- a/command/jsonconfig/config.go +++ b/command/jsonconfig/config.go @@ -34,8 +34,8 @@ type module struct { Outputs map[string]configOutput `json:"outputs,omitempty"` // Resources are sorted in a user-friendly order that is undefined at this // time, but consistent. - Resources []resource `json:"resources,omitempty"` - ModuleCalls []moduleCall `json:"module_calls,omitempty"` + Resources []resource `json:"resources,omitempty"` + ModuleCalls map[string]moduleCall `json:"module_calls,omitempty"` } type moduleCall struct { @@ -161,37 +161,39 @@ func marshalModule(c *configs.Config, schemas *terraform.Schemas) (module, error return module, nil } -func marshalModuleCalls(c *configs.Config, schemas *terraform.Schemas) []moduleCall { - var ret []moduleCall - for _, v := range c.Module.ModuleCalls { - mc := moduleCall{ - ResolvedSource: v.SourceAddr, +func marshalModuleCalls(c *configs.Config, schemas *terraform.Schemas) map[string]moduleCall { + ret := make(map[string]moduleCall) + for _, mc := range c.Module.ModuleCalls { + retMC := moduleCall{ + ResolvedSource: mc.SourceAddr, } - cExp := marshalExpression(v.Count) + cExp := marshalExpression(mc.Count) if !cExp.Empty() { - mc.CountExpression = &cExp + retMC.CountExpression = &cExp } else { - fExp := marshalExpression(v.ForEach) + fExp := marshalExpression(mc.ForEach) if !fExp.Empty() { - mc.ForEachExpression = &fExp + retMC.ForEachExpression = &fExp } } + // get the called module's variables so we can build up the expressions + childModule := c.Children[mc.Name] schema := &configschema.Block{} schema.Attributes = make(map[string]*configschema.Attribute) - for _, variable := range c.Module.Variables { + for _, variable := range childModule.Module.Variables { schema.Attributes[variable.Name] = &configschema.Attribute{ Required: variable.Default == cty.NilVal, } } - mc.Expressions = marshalExpressions(v.Config, schema) + + retMC.Expressions = marshalExpressions(mc.Config, schema) for _, cc := range c.Children { childModule, _ := marshalModule(cc, schemas) - mc.Module = childModule + retMC.Module = childModule } - ret = append(ret, mc) - + ret[mc.Name] = retMC } return ret diff --git a/command/jsonplan/plan.go b/command/jsonplan/plan.go index 91c92b6c9..4711707e2 100644 --- a/command/jsonplan/plan.go +++ b/command/jsonplan/plan.go @@ -16,6 +16,7 @@ import ( "github.com/hashicorp/terraform/states" "github.com/hashicorp/terraform/states/statefile" "github.com/hashicorp/terraform/terraform" + "github.com/hashicorp/terraform/version" ) // FormatVersion represents the version of the json format and will be @@ -26,8 +27,9 @@ const FormatVersion = "0.1" // Plan is the top-level representation of the json format of a plan. It includes // the complete config and current state. type plan struct { - FormatVersion string `json:"format_version,omitempty"` - PlannedValues stateValues `json:"planned_values,omitempty"` + FormatVersion string `json:"format_version,omitempty"` + TerraformVersion string `json:"terraform_version,omitempty"` + PlannedValues stateValues `json:"planned_values,omitempty"` // ResourceChanges are sorted in a user-friendly order that is undefined at // this time, but consistent. ResourceChanges []resourceChange `json:"resource_changes,omitempty"` @@ -83,6 +85,7 @@ func Marshal( ) ([]byte, error) { output := newPlan() + output.TerraformVersion = version.String() // output.PlannedValues err := output.marshalPlannedValues(p.Changes, schemas) diff --git a/command/jsonstate/state.go b/command/jsonstate/state.go index 6859b2b95..c491dc8da 100644 --- a/command/jsonstate/state.go +++ b/command/jsonstate/state.go @@ -77,7 +77,7 @@ type resource struct { // SchemaVersion indicates which version of the resource type schema the // "values" property conforms to. - SchemaVersion uint64 `json:"schema_version,omitempty"` + SchemaVersion uint64 `json:"schema_version"` // AttributeValues is the JSON representation of the attribute values of the // resource, whose structure depends on the resource type schema. Any