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.
This commit is contained in:
parent
0ff04b1232
commit
818b4ec068
|
@ -41,11 +41,12 @@ type module struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type moduleCall struct {
|
type moduleCall struct {
|
||||||
ResolvedSource string `json:"resolved_source,omitempty"`
|
Source string `json:"source,omitempty"`
|
||||||
Expressions map[string]interface{} `json:"expressions,omitempty"`
|
Expressions map[string]interface{} `json:"expressions,omitempty"`
|
||||||
CountExpression *expression `json:"count_expression,omitempty"`
|
CountExpression *expression `json:"count_expression,omitempty"`
|
||||||
ForEachExpression *expression `json:"for_each_expression,omitempty"`
|
ForEachExpression *expression `json:"for_each_expression,omitempty"`
|
||||||
Module module `json:"module,omitempty"`
|
Module module `json:"module,omitempty"`
|
||||||
|
VersionConstraint string `json:"version_constraint,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// variables is the JSON representation of the variables provided to the current
|
// 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)
|
ret := make(map[string]moduleCall)
|
||||||
for _, mc := range c.Module.ModuleCalls {
|
for _, mc := range c.Module.ModuleCalls {
|
||||||
retMC := moduleCall{
|
retMC := moduleCall{
|
||||||
ResolvedSource: mc.SourceAddr,
|
Source: mc.SourceAddr,
|
||||||
|
VersionConstraint: mc.Version.Required.String(),
|
||||||
}
|
}
|
||||||
cExp := marshalExpression(mc.Count)
|
cExp := marshalExpression(mc.Count)
|
||||||
if !cExp.Empty() {
|
if !cExp.Empty() {
|
||||||
|
|
|
@ -88,6 +88,7 @@ func marshalPlannedValues(changes *plans.Changes, schemas *terraform.Schemas) (m
|
||||||
// module -> [children modules]
|
// module -> [children modules]
|
||||||
moduleResourceMap := make(map[string][]addrs.AbsResourceInstance)
|
moduleResourceMap := make(map[string][]addrs.AbsResourceInstance)
|
||||||
moduleMap := make(map[string][]addrs.ModuleInstance)
|
moduleMap := make(map[string][]addrs.ModuleInstance)
|
||||||
|
seenModules := make(map[string]bool)
|
||||||
|
|
||||||
for _, resource := range changes.Resources {
|
for _, resource := range changes.Resources {
|
||||||
// if the resource is being deleted, skip over it.
|
// 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.
|
// root has no parents.
|
||||||
if containingModule != "" {
|
if containingModule != "" {
|
||||||
parent := resource.Addr.Module.Parent().String()
|
parent := resource.Addr.Module.Parent().String()
|
||||||
|
if !seenModules[parent] {
|
||||||
moduleMap[parent] = append(moduleMap[parent], resource.Addr.Module)
|
moduleMap[parent] = append(moduleMap[parent], resource.Addr.Module)
|
||||||
|
seenModules[parent] = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"github.com/google/go-cmp/cmp"
|
"github.com/google/go-cmp/cmp"
|
||||||
"github.com/hashicorp/terraform/addrs"
|
"github.com/hashicorp/terraform/addrs"
|
||||||
"github.com/hashicorp/terraform/configs/configschema"
|
"github.com/hashicorp/terraform/configs/configschema"
|
||||||
|
"github.com/hashicorp/terraform/helper/copy"
|
||||||
"github.com/hashicorp/terraform/plans"
|
"github.com/hashicorp/terraform/plans"
|
||||||
"github.com/hashicorp/terraform/providers"
|
"github.com/hashicorp/terraform/providers"
|
||||||
"github.com/hashicorp/terraform/states"
|
"github.com/hashicorp/terraform/states"
|
||||||
|
@ -146,24 +147,35 @@ func TestShow_json_output(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Run(entry.Name(), func(t *testing.T) {
|
t.Run(entry.Name(), func(t *testing.T) {
|
||||||
|
td := tempDir(t)
|
||||||
inputDir := filepath.Join(fixtureDir, entry.Name())
|
inputDir := filepath.Join(fixtureDir, entry.Name())
|
||||||
|
copy.CopyDir(inputDir, td)
|
||||||
cwd, err := os.Getwd()
|
defer os.RemoveAll(td)
|
||||||
if err != nil {
|
defer testChdir(t, td)()
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
if err := os.Chdir(inputDir); err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
defer os.Chdir(cwd)
|
|
||||||
|
|
||||||
p := showFixtureProvider()
|
p := showFixtureProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
pc := &PlanCommand{
|
m := Meta{
|
||||||
Meta: Meta{
|
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
testingOverrides: metaOverridesForProvider(p),
|
||||||
Ui: ui,
|
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{
|
args := []string{
|
||||||
|
@ -177,10 +189,7 @@ func TestShow_json_output(t *testing.T) {
|
||||||
// flush the plan output from the mock ui
|
// flush the plan output from the mock ui
|
||||||
ui.OutputWriter.Reset()
|
ui.OutputWriter.Reset()
|
||||||
sc := &ShowCommand{
|
sc := &ShowCommand{
|
||||||
Meta: Meta{
|
Meta: m,
|
||||||
testingOverrides: metaOverridesForProvider(p),
|
|
||||||
Ui: ui,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
args = []string{
|
args = []string{
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
module "test" {
|
||||||
|
source = "./foo"
|
||||||
|
test_var = "baz"
|
||||||
|
}
|
||||||
|
|
||||||
|
output "test" {
|
||||||
|
value = module.test.test
|
||||||
|
}
|
|
@ -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"}]}
|
|
@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue