diff --git a/command/jsonplan/plan.go b/command/jsonplan/plan.go index 4711707e2..11ceb44a3 100644 --- a/command/jsonplan/plan.go +++ b/command/jsonplan/plan.go @@ -29,6 +29,7 @@ const FormatVersion = "0.1" type plan struct { FormatVersion string `json:"format_version,omitempty"` TerraformVersion string `json:"terraform_version,omitempty"` + Variables variables `json:"variables,omitempty"` PlannedValues stateValues `json:"planned_values,omitempty"` // ResourceChanges are sorted in a user-friendly order that is undefined at // this time, but consistent. @@ -76,6 +77,14 @@ type output struct { Value json.RawMessage `json:"value,omitempty"` } +// variables is the JSON representation of the variables provided to the current +// plan. +type variables map[string]*variable + +type variable struct { + Value json.RawMessage `json:"value,omitempty"` +} + // Marshal returns the json encoding of a terraform plan. func Marshal( config *configs.Config, @@ -87,8 +96,13 @@ func Marshal( output := newPlan() output.TerraformVersion = version.String() + err := output.marshalPlanVariables(p.VariableValues, schemas) + if err != nil { + return nil, fmt.Errorf("error in marshalPlanVariables: %s", err) + } + // output.PlannedValues - err := output.marshalPlannedValues(p.Changes, schemas) + err = output.marshalPlannedValues(p.Changes, schemas) if err != nil { return nil, fmt.Errorf("error in marshalPlannedValues: %s", err) } @@ -122,6 +136,29 @@ func Marshal( return ret, err } +func (p *plan) marshalPlanVariables(vars map[string]plans.DynamicValue, schemas *terraform.Schemas) error { + if len(vars) == 0 { + return nil + } + + p.Variables = make(variables, len(vars)) + + for k, v := range vars { + val, err := v.Decode(cty.DynamicPseudoType) + if err != nil { + return err + } + valJSON, err := ctyjson.Marshal(val, val.Type()) + if err != nil { + return err + } + p.Variables[k] = &variable{ + Value: valJSON, + } + } + return nil +} + func (p *plan) marshalResourceChanges(changes *plans.Changes, schemas *terraform.Schemas) error { if changes == nil { // Nothing to do! diff --git a/command/jsonplan/values.go b/command/jsonplan/values.go index 2df050197..7ec437b24 100644 --- a/command/jsonplan/values.go +++ b/command/jsonplan/values.go @@ -166,6 +166,9 @@ func marshalPlanResources(changes *plans.Changes, ris []addrs.AbsResourceInstanc if changeV.After != cty.NilVal { if changeV.After.IsWhollyKnown() { resource.AttributeValues = marshalAttributeValues(changeV.After, schema) + } else { + knowns := omitUnknowns(changeV.After) + resource.AttributeValues = marshalAttributeValues(knowns, schema) } } diff --git a/command/jsonstate/state.go b/command/jsonstate/state.go index c491dc8da..0d1056c85 100644 --- a/command/jsonstate/state.go +++ b/command/jsonstate/state.go @@ -84,6 +84,13 @@ type resource struct { // unknown values are omitted or set to null, making them indistinguishable // from absent values. AttributeValues attributeValues `json:"values,omitempty"` + + // DependsOn contains a list of the resource's dependencies. The entries are + // addresses relative to the containing module. + DependsOn []string `json:"depends_on,omitempty"` + + // Tainted is true if the resource is tainted in terraform state. + Tainted bool `json:"tainted,omitempty"` } // attributeValues is the JSON representation of the attribute values of the @@ -276,6 +283,18 @@ func marshalResources(resources map[string]*states.Resource, schemas *terraform. resource.AttributeValues = marshalAttributeValues(riObj.Value, schema) + if len(riObj.Dependencies) > 0 { + dependencies := make([]string, len(riObj.Dependencies)) + for i, v := range riObj.Dependencies { + dependencies[i] = v.String() + } + resource.DependsOn = dependencies + } + + if riObj.Status == states.ObjectTainted { + resource.Tainted = true + } + ret = append(ret, resource) } diff --git a/command/show_test.go b/command/show_test.go index 5febe8578..2716d1935 100644 --- a/command/show_test.go +++ b/command/show_test.go @@ -312,9 +312,12 @@ func showFixturePlanFile(t *testing.T) string { } // this simplified plan struct allows us to preserve field order when marshaling -// the command output. +// the command output. NOTE: we are leaving "terraform_version" out of this test +// to avoid needing to constantly update the expected output; as a potential +// TODO we could write a jsonplan compare function. type plan struct { FormatVersion string `json:"format_version,omitempty"` + Variables map[string]interface{} `json:"variables,omitempty"` PlannedValues map[string]interface{} `json:"planned_values,omitempty"` ResourceChanges []interface{} `json:"resource_changes,omitempty"` OutputChanges map[string]interface{} `json:"output_changes,omitempty"` diff --git a/command/test-fixtures/show-json/basic-create/output.json b/command/test-fixtures/show-json/basic-create/output.json index 8db83be19..d976addd1 100644 --- a/command/test-fixtures/show-json/basic-create/output.json +++ b/command/test-fixtures/show-json/basic-create/output.json @@ -1,5 +1,10 @@ { "format_version": "0.1", + "variables": { + "test_var": { + "value": "bar" + } + }, "planned_values": { "outputs": { "test": { @@ -16,7 +21,10 @@ "type": "test_instance", "name": "test", "provider_name": "test", - "schema_version": 0 + "schema_version": 0, + "values": { + "ami": "bar" + } }, { "address": "test_instance.test[1]", @@ -25,7 +33,10 @@ "type": "test_instance", "name": "test", "provider_name": "test", - "schema_version": 0 + "schema_version": 0, + "values": { + "ami": "bar" + } }, { "address": "test_instance.test[2]", @@ -34,7 +45,10 @@ "type": "test_instance", "name": "test", "provider_name": "test", - "schema_version": 0 + "schema_version": 0, + "values": { + "ami": "bar" + } } ] } diff --git a/command/test-fixtures/show-json/basic-delete/output.json b/command/test-fixtures/show-json/basic-delete/output.json index 837ed5d01..1b42c9e87 100644 --- a/command/test-fixtures/show-json/basic-delete/output.json +++ b/command/test-fixtures/show-json/basic-delete/output.json @@ -1,5 +1,10 @@ { "format_version": "0.1", + "variables": { + "test_var": { + "value": "bar" + } + }, "planned_values": { "outputs": { "test": { diff --git a/command/test-fixtures/show-json/basic-update/output.json b/command/test-fixtures/show-json/basic-update/output.json index 4f5f115fb..59eadb986 100644 --- a/command/test-fixtures/show-json/basic-update/output.json +++ b/command/test-fixtures/show-json/basic-update/output.json @@ -1,5 +1,10 @@ { "format_version": "0.1", + "variables": { + "test_var": { + "value": "bar" + } + }, "planned_values": { "outputs": { "test": {