From 818b4ec06820e438147a79fef75281ca1e2df65d Mon Sep 17 00:00:00 2001 From: Kristin Laemmert Date: Tue, 19 Feb 2019 08:12:33 -0800 Subject: [PATCH] command/show: add "module_version" to "module_calls" in config (#20367) * command/show: add "module_version" to "module_calls" in config portion of `terraform show`. Also extended the `terraform show -json` test to run `init` so we could add examples with modules. This does _not_ test the "module_version" yet, but it _did_ help expose a bug in jsonplan where modules were duplicated. This is also fixed in this PR. * command/jsonconfig: rename version to version_constraint and resolved_source to source. --- command/jsonconfig/config.go | 6 +- command/jsonplan/values.go | 6 +- command/show_test.go | 43 ++-- .../show-json/modules/foo/main.tf | 11 + .../test-fixtures/show-json/modules/main.tf | 8 + .../show-json/modules/modules.json | 1 + .../show-json/modules/output.json | 193 ++++++++++++++++++ 7 files changed, 248 insertions(+), 20 deletions(-) create mode 100644 command/test-fixtures/show-json/modules/foo/main.tf create mode 100644 command/test-fixtures/show-json/modules/main.tf create mode 100644 command/test-fixtures/show-json/modules/modules.json create mode 100644 command/test-fixtures/show-json/modules/output.json diff --git a/command/jsonconfig/config.go b/command/jsonconfig/config.go index 3455450ed..e0a5eb30c 100644 --- a/command/jsonconfig/config.go +++ b/command/jsonconfig/config.go @@ -41,11 +41,12 @@ type module struct { } type moduleCall struct { - ResolvedSource string `json:"resolved_source,omitempty"` + Source string `json:"source,omitempty"` Expressions map[string]interface{} `json:"expressions,omitempty"` CountExpression *expression `json:"count_expression,omitempty"` ForEachExpression *expression `json:"for_each_expression,omitempty"` Module module `json:"module,omitempty"` + VersionConstraint string `json:"version_constraint,omitempty"` } // variables is the JSON representation of the variables provided to the current @@ -197,7 +198,8 @@ func marshalModuleCalls(c *configs.Config, schemas *terraform.Schemas) map[strin ret := make(map[string]moduleCall) for _, mc := range c.Module.ModuleCalls { retMC := moduleCall{ - ResolvedSource: mc.SourceAddr, + Source: mc.SourceAddr, + VersionConstraint: mc.Version.Required.String(), } cExp := marshalExpression(mc.Count) if !cExp.Empty() { diff --git a/command/jsonplan/values.go b/command/jsonplan/values.go index 7ec437b24..7e3d268ce 100644 --- a/command/jsonplan/values.go +++ b/command/jsonplan/values.go @@ -88,6 +88,7 @@ func marshalPlannedValues(changes *plans.Changes, schemas *terraform.Schemas) (m // module -> [children modules] moduleResourceMap := make(map[string][]addrs.AbsResourceInstance) moduleMap := make(map[string][]addrs.ModuleInstance) + seenModules := make(map[string]bool) for _, resource := range changes.Resources { // if the resource is being deleted, skip over it. @@ -98,7 +99,10 @@ func marshalPlannedValues(changes *plans.Changes, schemas *terraform.Schemas) (m // root has no parents. if containingModule != "" { parent := resource.Addr.Module.Parent().String() - moduleMap[parent] = append(moduleMap[parent], resource.Addr.Module) + if !seenModules[parent] { + moduleMap[parent] = append(moduleMap[parent], resource.Addr.Module) + seenModules[parent] = true + } } } } diff --git a/command/show_test.go b/command/show_test.go index e36b2b0b7..9ea3c5c87 100644 --- a/command/show_test.go +++ b/command/show_test.go @@ -10,6 +10,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/hashicorp/terraform/addrs" "github.com/hashicorp/terraform/configs/configschema" + "github.com/hashicorp/terraform/helper/copy" "github.com/hashicorp/terraform/plans" "github.com/hashicorp/terraform/providers" "github.com/hashicorp/terraform/states" @@ -146,25 +147,36 @@ func TestShow_json_output(t *testing.T) { } t.Run(entry.Name(), func(t *testing.T) { + td := tempDir(t) inputDir := filepath.Join(fixtureDir, entry.Name()) - - cwd, err := os.Getwd() - if err != nil { - t.Fatalf("err: %s", err) - } - if err := os.Chdir(inputDir); err != nil { - t.Fatalf("err: %s", err) - } - defer os.Chdir(cwd) + copy.CopyDir(inputDir, td) + defer os.RemoveAll(td) + defer testChdir(t, td)() p := showFixtureProvider() ui := new(cli.MockUi) - pc := &PlanCommand{ - Meta: Meta{ - testingOverrides: metaOverridesForProvider(p), - Ui: ui, + m := Meta{ + testingOverrides: metaOverridesForProvider(p), + Ui: ui, + } + + // init + ic := &InitCommand{ + Meta: m, + providerInstaller: &mockProviderInstaller{ + Providers: map[string][]string{ + "test": []string{"1.2.3"}, + }, + Dir: m.pluginDir(), }, } + if code := ic.Run([]string{}); code != 0 { + t.Fatalf("init failed\n%s", ui.ErrorWriter) + } + + pc := &PlanCommand{ + Meta: m, + } args := []string{ "-out=terraform.plan", @@ -177,10 +189,7 @@ func TestShow_json_output(t *testing.T) { // flush the plan output from the mock ui ui.OutputWriter.Reset() sc := &ShowCommand{ - Meta: Meta{ - testingOverrides: metaOverridesForProvider(p), - Ui: ui, - }, + Meta: m, } args = []string{ diff --git a/command/test-fixtures/show-json/modules/foo/main.tf b/command/test-fixtures/show-json/modules/foo/main.tf new file mode 100644 index 000000000..d9e282763 --- /dev/null +++ b/command/test-fixtures/show-json/modules/foo/main.tf @@ -0,0 +1,11 @@ +variable "test_var" { + default = "bar" +} +resource "test_instance" "test" { + ami = var.test_var + count = 3 +} + +output "test" { + value = var.test_var +} diff --git a/command/test-fixtures/show-json/modules/main.tf b/command/test-fixtures/show-json/modules/main.tf new file mode 100644 index 000000000..4b81fcf5f --- /dev/null +++ b/command/test-fixtures/show-json/modules/main.tf @@ -0,0 +1,8 @@ +module "test" { + source = "./foo" + test_var = "baz" +} + +output "test" { + value = module.test.test +} diff --git a/command/test-fixtures/show-json/modules/modules.json b/command/test-fixtures/show-json/modules/modules.json new file mode 100644 index 000000000..54b418abf --- /dev/null +++ b/command/test-fixtures/show-json/modules/modules.json @@ -0,0 +1 @@ +{"Modules":[{"Key":"","Source":"","Dir":"/Users/kristin/go/src/github.com/hashicorp/terraform/command/test-fixtures/show-json/modules"},{"Key":"test","Source":"./foo","Dir":"/Users/kristin/go/src/github.com/hashicorp/terraform/command/test-fixtures/show-json/modules/foo"}]} \ No newline at end of file diff --git a/command/test-fixtures/show-json/modules/output.json b/command/test-fixtures/show-json/modules/output.json new file mode 100644 index 000000000..cbc284c7e --- /dev/null +++ b/command/test-fixtures/show-json/modules/output.json @@ -0,0 +1,193 @@ +{ + "format_version": "0.1", + "planned_values": { + "outputs": { + "test": { + "sensitive": false, + "value": "baz" + } + }, + "root_module": { + "child_modules": [ + { + "resources": [ + { + "address": "module.test.test_instance.test[0]", + "mode": "managed", + "type": "test_instance", + "name": "test", + "index": 0, + "provider_name": "test", + "schema_version": 0, + "values": { + "ami": "baz" + } + }, + { + "address": "module.test.test_instance.test[1]", + "mode": "managed", + "type": "test_instance", + "name": "test", + "index": 1, + "provider_name": "test", + "schema_version": 0, + "values": { + "ami": "baz" + } + }, + { + "address": "module.test.test_instance.test[2]", + "mode": "managed", + "type": "test_instance", + "name": "test", + "index": 2, + "provider_name": "test", + "schema_version": 0, + "values": { + "ami": "baz" + } + } + ], + "address": "module.test" + } + ] + } + }, + "resource_changes": [ + { + "address": "module.test.test_instance.test[0]", + "module_address": "module.test", + "mode": "managed", + "type": "test_instance", + "name": "test", + "index": 0, + "deposed": true, + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "ami": "baz" + }, + "after_unknown": { + "ami": false, + "id": true + } + } + }, + { + "address": "module.test.test_instance.test[1]", + "module_address": "module.test", + "mode": "managed", + "type": "test_instance", + "name": "test", + "index": 1, + "deposed": true, + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "ami": "baz" + }, + "after_unknown": { + "ami": false, + "id": true + } + } + }, + { + "address": "module.test.test_instance.test[2]", + "module_address": "module.test", + "mode": "managed", + "type": "test_instance", + "name": "test", + "index": 2, + "deposed": true, + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "ami": "baz" + }, + "after_unknown": { + "ami": false, + "id": true + } + } + } + ], + "output_changes": { + "test": { + "actions": [ + "create" + ], + "before": null, + "after": "baz", + "after_unknown": false + } + }, + "configuration": { + "root_module": { + "outputs": { + "test": { + "expression": { + "references": [ + "module.test.test" + ] + } + } + }, + "module_calls": { + "test": { + "source": "./foo", + "expressions": { + "test_var": { + "constant_value": "baz" + } + }, + "module": { + "outputs": { + "test": { + "expression": { + "references": [ + "var.test_var" + ] + } + } + }, + "resources": [ + { + "address": "test_instance.test", + "mode": "managed", + "type": "test_instance", + "name": "test", + "provider_config_key": "provider.test", + "expressions": { + "ami": { + "references": [ + "var.test_var" + ] + } + }, + "schema_version": 0, + "count_expression": { + "constant_value": 3 + } + } + ], + "variables": { + "test_var": { + "default": "bar" + } + } + } + } + } + } + } +} \ No newline at end of file