command/show: improvements to show -json output (#20110)
* terraform_version is now included in state * provisioner "name" is now provisioner "type"
This commit is contained in:
parent
a30bd5cdd4
commit
514ac6b890
|
@ -83,7 +83,7 @@ type configOutput struct {
|
|||
}
|
||||
|
||||
type provisioner struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
Expressions map[string]interface{} `json:"expressions,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -242,7 +242,7 @@ func marshalResources(resources map[string]*configs.Resource, schemas *terraform
|
|||
for _, p := range v.Managed.Provisioners {
|
||||
schema := schemas.ProvisionerConfig(p.Type)
|
||||
prov := provisioner{
|
||||
Name: p.Type,
|
||||
Type: p.Type,
|
||||
Expressions: marshalExpressions(p.Config, schema),
|
||||
}
|
||||
provisioners = append(provisioners, prov)
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
"github.com/hashicorp/terraform/configs"
|
||||
"github.com/hashicorp/terraform/plans"
|
||||
"github.com/hashicorp/terraform/states"
|
||||
"github.com/hashicorp/terraform/states/statefile"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
|
||||
ctyjson "github.com/zclconf/go-cty/cty/json"
|
||||
|
@ -76,7 +77,7 @@ type output struct {
|
|||
func Marshal(
|
||||
config *configs.Config,
|
||||
p *plans.Plan,
|
||||
s *states.State,
|
||||
sf *statefile.File,
|
||||
schemas *terraform.Schemas,
|
||||
) ([]byte, error) {
|
||||
|
||||
|
@ -101,7 +102,7 @@ func Marshal(
|
|||
}
|
||||
|
||||
// output.PriorState
|
||||
output.PriorState, err = jsonstate.Marshal(s, schemas)
|
||||
output.PriorState, err = jsonstate.Marshal(sf, schemas)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error marshaling prior state: %s", err)
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/hashicorp/terraform/addrs"
|
||||
"github.com/hashicorp/terraform/configs/configschema"
|
||||
"github.com/hashicorp/terraform/states"
|
||||
"github.com/hashicorp/terraform/states/statefile"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
||||
|
@ -22,8 +23,9 @@ const FormatVersion = "0.1"
|
|||
// state is the top-level representation of the json format of a terraform
|
||||
// state.
|
||||
type state struct {
|
||||
FormatVersion string `json:"format_version,omitempty"`
|
||||
Values stateValues `json:"values,omitempty"`
|
||||
FormatVersion string `json:"format_version,omitempty"`
|
||||
TerraformVersion string `json:"terraform_version"`
|
||||
Values stateValues `json:"values,omitempty"`
|
||||
}
|
||||
|
||||
// stateValues is the common representation of resolved values for both the prior
|
||||
|
@ -109,15 +111,16 @@ func newState() *state {
|
|||
}
|
||||
|
||||
// Marshal returns the json encoding of a terraform state.
|
||||
func Marshal(s *states.State, schemas *terraform.Schemas) ([]byte, error) {
|
||||
if s.Empty() {
|
||||
func Marshal(sf *statefile.File, schemas *terraform.Schemas) ([]byte, error) {
|
||||
if sf == nil || sf.State.Empty() {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
output := newState()
|
||||
output.TerraformVersion = sf.TerraformVersion.String()
|
||||
|
||||
// output.StateValues
|
||||
err := output.marshalStateValues(s, schemas)
|
||||
err := output.marshalStateValues(sf.State, schemas)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -6,14 +6,13 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform/backend"
|
||||
"github.com/hashicorp/terraform/plans/planfile"
|
||||
"github.com/hashicorp/terraform/states/statefile"
|
||||
"github.com/hashicorp/terraform/tfdiags"
|
||||
|
||||
"github.com/hashicorp/terraform/command/format"
|
||||
"github.com/hashicorp/terraform/command/jsonplan"
|
||||
"github.com/hashicorp/terraform/plans"
|
||||
"github.com/hashicorp/terraform/states"
|
||||
"github.com/hashicorp/terraform/plans/planfile"
|
||||
"github.com/hashicorp/terraform/states/statefile"
|
||||
"github.com/hashicorp/terraform/states/statemgr"
|
||||
"github.com/hashicorp/terraform/tfdiags"
|
||||
)
|
||||
|
||||
// ShowCommand is a Command implementation that reads and outputs the
|
||||
|
@ -103,7 +102,7 @@ func (c *ShowCommand) Run(args []string) int {
|
|||
|
||||
var planErr, stateErr error
|
||||
var plan *plans.Plan
|
||||
var state *states.State
|
||||
var stateFile *statefile.File
|
||||
|
||||
// if a path was provided, try to read it as a path to a planfile
|
||||
// if that fails, try to read the cli argument as a path to a statefile
|
||||
|
@ -116,7 +115,7 @@ func (c *ShowCommand) Run(args []string) int {
|
|||
c.Ui.Error("Error: JSON output not available for state")
|
||||
return 1
|
||||
}
|
||||
state, stateErr = getStateFromPath(path)
|
||||
stateFile, stateErr = getStateFromPath(path)
|
||||
if stateErr != nil {
|
||||
c.Ui.Error(fmt.Sprintf(
|
||||
"Terraform couldn't read the given file as a state or plan file.\n"+
|
||||
|
@ -130,9 +129,9 @@ func (c *ShowCommand) Run(args []string) int {
|
|||
}
|
||||
}
|
||||
|
||||
if state == nil {
|
||||
if stateFile == nil {
|
||||
env := c.Workspace()
|
||||
state, stateErr = getStateFromEnv(b, env)
|
||||
stateFile, stateErr = getStateFromEnv(b, env)
|
||||
if err != nil {
|
||||
c.Ui.Error(err.Error())
|
||||
return 1
|
||||
|
@ -142,7 +141,7 @@ func (c *ShowCommand) Run(args []string) int {
|
|||
// This is an odd-looking check, because it's ok if we have a plan and an
|
||||
// empty state, and we've already validated that any command-line arguments
|
||||
// have been read successfully
|
||||
if plan == nil && state == nil {
|
||||
if plan == nil && stateFile == nil {
|
||||
c.Ui.Output("No state.")
|
||||
return 0
|
||||
}
|
||||
|
@ -150,7 +149,7 @@ func (c *ShowCommand) Run(args []string) int {
|
|||
if plan != nil {
|
||||
if jsonOutput == true {
|
||||
config := ctx.Config()
|
||||
jsonPlan, err := jsonplan.Marshal(config, plan, state, schemas)
|
||||
jsonPlan, err := jsonplan.Marshal(config, plan, stateFile, schemas)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Failed to marshal plan to json: %s", err))
|
||||
return 1
|
||||
|
@ -164,7 +163,7 @@ func (c *ShowCommand) Run(args []string) int {
|
|||
}
|
||||
|
||||
c.Ui.Output(format.State(&format.StateOpts{
|
||||
State: state,
|
||||
State: stateFile.State,
|
||||
Color: c.Colorize(),
|
||||
Schemas: schemas,
|
||||
}))
|
||||
|
@ -207,8 +206,8 @@ func getPlanFromPath(path string) (*plans.Plan, error) {
|
|||
return plan, nil
|
||||
}
|
||||
|
||||
// getStateFromPath returns a State if the user-supplied path points to a statefile.
|
||||
func getStateFromPath(path string) (*states.State, error) {
|
||||
// getStateFromPath returns a statefile if the user-supplied path points to a statefile.
|
||||
func getStateFromPath(path string) (*statefile.File, error) {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error loading statefile: %s", err)
|
||||
|
@ -220,11 +219,11 @@ func getStateFromPath(path string) (*states.State, error) {
|
|||
if err != nil {
|
||||
return nil, fmt.Errorf("Error reading %s as a statefile: %s", path, err)
|
||||
}
|
||||
return stateFile.State, nil
|
||||
return stateFile, nil
|
||||
}
|
||||
|
||||
// getStateFromEnv returns the State for the current workspace, if available.
|
||||
func getStateFromEnv(b backend.Backend, env string) (*states.State, error) {
|
||||
func getStateFromEnv(b backend.Backend, env string) (*statefile.File, error) {
|
||||
// Get the state
|
||||
stateStore, err := b.StateMgr(env)
|
||||
if err != nil {
|
||||
|
@ -235,6 +234,7 @@ func getStateFromEnv(b backend.Backend, env string) (*states.State, error) {
|
|||
return nil, fmt.Errorf("Failed to load state: %s", err)
|
||||
}
|
||||
|
||||
state := stateStore.State()
|
||||
return state, nil
|
||||
sf := statemgr.Export(stateStore)
|
||||
|
||||
return sf, nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue