2014-07-13 04:47:31 +02:00
|
|
|
package command
|
|
|
|
|
|
|
|
import (
|
|
|
|
"flag"
|
|
|
|
"fmt"
|
|
|
|
"os"
|
|
|
|
"strings"
|
|
|
|
|
2018-09-25 00:00:07 +02:00
|
|
|
"github.com/hashicorp/terraform/backend"
|
terraform: Ugly huge change to weave in new State and Plan types
Due to how often the state and plan types are referenced throughout
Terraform, there isn't a great way to switch them out gradually. As a
consequence, this huge commit gets us from the old world to a _compilable_
new world, but still has a large number of known test failures due to
key functionality being stubbed out.
The stubs here are for anything that interacts with providers, since we
now need to do the follow-up work to similarly replace the old
terraform.ResourceProvider interface with its replacement in the new
"providers" package. That work, along with work to fix the remaining
failing tests, will follow in subsequent commits.
The aim here was to replace all references to terraform.State and its
downstream types with states.State, terraform.Plan with plans.Plan,
state.State with statemgr.State, and switch to the new implementations of
the state and plan file formats. However, due to the number of times those
types are used, this also ended up affecting numerous other parts of core
such as terraform.Hook, the backend.Backend interface, and most of the CLI
commands.
Just as with 5861dbf3fc49b19587a31816eb06f511ab861bb4 before, I apologize
in advance to the person who inevitably just found this huge commit while
spelunking through the commit history.
2018-08-14 23:24:45 +02:00
|
|
|
"github.com/hashicorp/terraform/plans/planfile"
|
|
|
|
"github.com/hashicorp/terraform/states/statefile"
|
2018-09-25 00:00:07 +02:00
|
|
|
"github.com/hashicorp/terraform/tfdiags"
|
terraform: Ugly huge change to weave in new State and Plan types
Due to how often the state and plan types are referenced throughout
Terraform, there isn't a great way to switch them out gradually. As a
consequence, this huge commit gets us from the old world to a _compilable_
new world, but still has a large number of known test failures due to
key functionality being stubbed out.
The stubs here are for anything that interacts with providers, since we
now need to do the follow-up work to similarly replace the old
terraform.ResourceProvider interface with its replacement in the new
"providers" package. That work, along with work to fix the remaining
failing tests, will follow in subsequent commits.
The aim here was to replace all references to terraform.State and its
downstream types with states.State, terraform.Plan with plans.Plan,
state.State with statemgr.State, and switch to the new implementations of
the state and plan file formats. However, due to the number of times those
types are used, this also ended up affecting numerous other parts of core
such as terraform.Hook, the backend.Backend interface, and most of the CLI
commands.
Just as with 5861dbf3fc49b19587a31816eb06f511ab861bb4 before, I apologize
in advance to the person who inevitably just found this huge commit while
spelunking through the commit history.
2018-08-14 23:24:45 +02:00
|
|
|
|
2017-01-19 05:50:45 +01:00
|
|
|
"github.com/hashicorp/terraform/command/format"
|
terraform: Ugly huge change to weave in new State and Plan types
Due to how often the state and plan types are referenced throughout
Terraform, there isn't a great way to switch them out gradually. As a
consequence, this huge commit gets us from the old world to a _compilable_
new world, but still has a large number of known test failures due to
key functionality being stubbed out.
The stubs here are for anything that interacts with providers, since we
now need to do the follow-up work to similarly replace the old
terraform.ResourceProvider interface with its replacement in the new
"providers" package. That work, along with work to fix the remaining
failing tests, will follow in subsequent commits.
The aim here was to replace all references to terraform.State and its
downstream types with states.State, terraform.Plan with plans.Plan,
state.State with statemgr.State, and switch to the new implementations of
the state and plan file formats. However, due to the number of times those
types are used, this also ended up affecting numerous other parts of core
such as terraform.Hook, the backend.Backend interface, and most of the CLI
commands.
Just as with 5861dbf3fc49b19587a31816eb06f511ab861bb4 before, I apologize
in advance to the person who inevitably just found this huge commit while
spelunking through the commit history.
2018-08-14 23:24:45 +02:00
|
|
|
"github.com/hashicorp/terraform/plans"
|
|
|
|
"github.com/hashicorp/terraform/states"
|
2014-07-13 04:47:31 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
// ShowCommand is a Command implementation that reads and outputs the
|
|
|
|
// contents of a Terraform plan or state file.
|
|
|
|
type ShowCommand struct {
|
2014-07-13 05:21:46 +02:00
|
|
|
Meta
|
2014-07-13 04:47:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (c *ShowCommand) Run(args []string) int {
|
2017-03-08 05:09:48 +01:00
|
|
|
args, err := c.Meta.process(args, false)
|
|
|
|
if err != nil {
|
|
|
|
return 1
|
|
|
|
}
|
2014-07-13 05:21:46 +02:00
|
|
|
|
2014-07-13 04:47:31 +02:00
|
|
|
cmdFlags := flag.NewFlagSet("show", flag.ContinueOnError)
|
2018-09-24 18:30:39 +02:00
|
|
|
|
2014-07-13 04:47:31 +02:00
|
|
|
cmdFlags.Usage = func() { c.Ui.Error(c.Help()) }
|
|
|
|
if err := cmdFlags.Parse(args); err != nil {
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
args = cmdFlags.Args()
|
2014-10-11 21:56:55 +02:00
|
|
|
if len(args) > 1 {
|
2014-07-13 04:47:31 +02:00
|
|
|
c.Ui.Error(
|
2014-10-11 21:56:55 +02:00
|
|
|
"The show command expects at most one argument with the path\n" +
|
2014-07-13 04:47:31 +02:00
|
|
|
"to a Terraform state or plan file.\n")
|
|
|
|
cmdFlags.Usage()
|
|
|
|
return 1
|
|
|
|
}
|
2014-10-11 21:56:55 +02:00
|
|
|
|
2018-09-25 00:00:07 +02:00
|
|
|
var diags tfdiags.Diagnostics
|
|
|
|
|
|
|
|
// Load the backend
|
|
|
|
b, backendDiags := c.Backend(nil)
|
|
|
|
diags = diags.Append(backendDiags)
|
|
|
|
if backendDiags.HasErrors() {
|
|
|
|
c.showDiagnostics(diags)
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
// We require a local backend
|
|
|
|
local, ok := b.(backend.Local)
|
|
|
|
if !ok {
|
|
|
|
c.showDiagnostics(diags) // in case of any warnings in here
|
|
|
|
c.Ui.Error(ErrUnsupportedLocalOp)
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
2018-10-09 23:57:03 +02:00
|
|
|
// the show command expects the config dir to always be the cwd
|
|
|
|
cwd, err := os.Getwd()
|
|
|
|
if err != nil {
|
|
|
|
c.Ui.Error(fmt.Sprintf("Error getting cwd: %s", err))
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
2018-09-25 00:00:07 +02:00
|
|
|
// Build the operation
|
|
|
|
opReq := c.Operation(b)
|
2018-10-09 23:57:03 +02:00
|
|
|
opReq.ConfigDir = cwd
|
2018-09-25 00:00:07 +02:00
|
|
|
opReq.ConfigLoader, err = c.initConfigLoader()
|
|
|
|
if err != nil {
|
|
|
|
diags = diags.Append(err)
|
|
|
|
c.showDiagnostics(diags)
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the context
|
|
|
|
ctx, _, ctxDiags := local.Context(opReq)
|
|
|
|
diags = diags.Append(ctxDiags)
|
|
|
|
if ctxDiags.HasErrors() {
|
|
|
|
c.showDiagnostics(diags)
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
schemas := ctx.Schemas()
|
|
|
|
|
|
|
|
env := c.Workspace()
|
|
|
|
|
2015-02-22 01:04:32 +01:00
|
|
|
var planErr, stateErr error
|
2014-10-11 21:56:55 +02:00
|
|
|
var path string
|
terraform: Ugly huge change to weave in new State and Plan types
Due to how often the state and plan types are referenced throughout
Terraform, there isn't a great way to switch them out gradually. As a
consequence, this huge commit gets us from the old world to a _compilable_
new world, but still has a large number of known test failures due to
key functionality being stubbed out.
The stubs here are for anything that interacts with providers, since we
now need to do the follow-up work to similarly replace the old
terraform.ResourceProvider interface with its replacement in the new
"providers" package. That work, along with work to fix the remaining
failing tests, will follow in subsequent commits.
The aim here was to replace all references to terraform.State and its
downstream types with states.State, terraform.Plan with plans.Plan,
state.State with statemgr.State, and switch to the new implementations of
the state and plan file formats. However, due to the number of times those
types are used, this also ended up affecting numerous other parts of core
such as terraform.Hook, the backend.Backend interface, and most of the CLI
commands.
Just as with 5861dbf3fc49b19587a31816eb06f511ab861bb4 before, I apologize
in advance to the person who inevitably just found this huge commit while
spelunking through the commit history.
2018-08-14 23:24:45 +02:00
|
|
|
var plan *plans.Plan
|
|
|
|
var state *states.State
|
2014-10-11 21:56:55 +02:00
|
|
|
if len(args) > 0 {
|
|
|
|
path = args[0]
|
terraform: Ugly huge change to weave in new State and Plan types
Due to how often the state and plan types are referenced throughout
Terraform, there isn't a great way to switch them out gradually. As a
consequence, this huge commit gets us from the old world to a _compilable_
new world, but still has a large number of known test failures due to
key functionality being stubbed out.
The stubs here are for anything that interacts with providers, since we
now need to do the follow-up work to similarly replace the old
terraform.ResourceProvider interface with its replacement in the new
"providers" package. That work, along with work to fix the remaining
failing tests, will follow in subsequent commits.
The aim here was to replace all references to terraform.State and its
downstream types with states.State, terraform.Plan with plans.Plan,
state.State with statemgr.State, and switch to the new implementations of
the state and plan file formats. However, due to the number of times those
types are used, this also ended up affecting numerous other parts of core
such as terraform.Hook, the backend.Backend interface, and most of the CLI
commands.
Just as with 5861dbf3fc49b19587a31816eb06f511ab861bb4 before, I apologize
in advance to the person who inevitably just found this huge commit while
spelunking through the commit history.
2018-08-14 23:24:45 +02:00
|
|
|
pr, err := planfile.Open(path)
|
2014-12-06 00:38:41 +01:00
|
|
|
if err != nil {
|
terraform: Ugly huge change to weave in new State and Plan types
Due to how often the state and plan types are referenced throughout
Terraform, there isn't a great way to switch them out gradually. As a
consequence, this huge commit gets us from the old world to a _compilable_
new world, but still has a large number of known test failures due to
key functionality being stubbed out.
The stubs here are for anything that interacts with providers, since we
now need to do the follow-up work to similarly replace the old
terraform.ResourceProvider interface with its replacement in the new
"providers" package. That work, along with work to fix the remaining
failing tests, will follow in subsequent commits.
The aim here was to replace all references to terraform.State and its
downstream types with states.State, terraform.Plan with plans.Plan,
state.State with statemgr.State, and switch to the new implementations of
the state and plan file formats. However, due to the number of times those
types are used, this also ended up affecting numerous other parts of core
such as terraform.Hook, the backend.Backend interface, and most of the CLI
commands.
Just as with 5861dbf3fc49b19587a31816eb06f511ab861bb4 before, I apologize
in advance to the person who inevitably just found this huge commit while
spelunking through the commit history.
2018-08-14 23:24:45 +02:00
|
|
|
f, err := os.Open(path)
|
|
|
|
if err != nil {
|
|
|
|
c.Ui.Error(fmt.Sprintf("Error loading file: %s", err))
|
2014-12-06 00:38:41 +01:00
|
|
|
return 1
|
|
|
|
}
|
terraform: Ugly huge change to weave in new State and Plan types
Due to how often the state and plan types are referenced throughout
Terraform, there isn't a great way to switch them out gradually. As a
consequence, this huge commit gets us from the old world to a _compilable_
new world, but still has a large number of known test failures due to
key functionality being stubbed out.
The stubs here are for anything that interacts with providers, since we
now need to do the follow-up work to similarly replace the old
terraform.ResourceProvider interface with its replacement in the new
"providers" package. That work, along with work to fix the remaining
failing tests, will follow in subsequent commits.
The aim here was to replace all references to terraform.State and its
downstream types with states.State, terraform.Plan with plans.Plan,
state.State with statemgr.State, and switch to the new implementations of
the state and plan file formats. However, due to the number of times those
types are used, this also ended up affecting numerous other parts of core
such as terraform.Hook, the backend.Backend interface, and most of the CLI
commands.
Just as with 5861dbf3fc49b19587a31816eb06f511ab861bb4 before, I apologize
in advance to the person who inevitably just found this huge commit while
spelunking through the commit history.
2018-08-14 23:24:45 +02:00
|
|
|
defer f.Close()
|
2014-07-13 04:47:31 +02:00
|
|
|
|
terraform: Ugly huge change to weave in new State and Plan types
Due to how often the state and plan types are referenced throughout
Terraform, there isn't a great way to switch them out gradually. As a
consequence, this huge commit gets us from the old world to a _compilable_
new world, but still has a large number of known test failures due to
key functionality being stubbed out.
The stubs here are for anything that interacts with providers, since we
now need to do the follow-up work to similarly replace the old
terraform.ResourceProvider interface with its replacement in the new
"providers" package. That work, along with work to fix the remaining
failing tests, will follow in subsequent commits.
The aim here was to replace all references to terraform.State and its
downstream types with states.State, terraform.Plan with plans.Plan,
state.State with statemgr.State, and switch to the new implementations of
the state and plan file formats. However, due to the number of times those
types are used, this also ended up affecting numerous other parts of core
such as terraform.Hook, the backend.Backend interface, and most of the CLI
commands.
Just as with 5861dbf3fc49b19587a31816eb06f511ab861bb4 before, I apologize
in advance to the person who inevitably just found this huge commit while
spelunking through the commit history.
2018-08-14 23:24:45 +02:00
|
|
|
var stateFile *statefile.File
|
|
|
|
stateFile, err = statefile.Read(f)
|
2014-12-06 00:38:41 +01:00
|
|
|
if err != nil {
|
|
|
|
stateErr = err
|
terraform: Ugly huge change to weave in new State and Plan types
Due to how often the state and plan types are referenced throughout
Terraform, there isn't a great way to switch them out gradually. As a
consequence, this huge commit gets us from the old world to a _compilable_
new world, but still has a large number of known test failures due to
key functionality being stubbed out.
The stubs here are for anything that interacts with providers, since we
now need to do the follow-up work to similarly replace the old
terraform.ResourceProvider interface with its replacement in the new
"providers" package. That work, along with work to fix the remaining
failing tests, will follow in subsequent commits.
The aim here was to replace all references to terraform.State and its
downstream types with states.State, terraform.Plan with plans.Plan,
state.State with statemgr.State, and switch to the new implementations of
the state and plan file formats. However, due to the number of times those
types are used, this also ended up affecting numerous other parts of core
such as terraform.Hook, the backend.Backend interface, and most of the CLI
commands.
Just as with 5861dbf3fc49b19587a31816eb06f511ab861bb4 before, I apologize
in advance to the person who inevitably just found this huge commit while
spelunking through the commit history.
2018-08-14 23:24:45 +02:00
|
|
|
} else {
|
|
|
|
state = stateFile.State
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
plan, err = pr.ReadPlan()
|
|
|
|
if err != nil {
|
|
|
|
planErr = err
|
2014-12-06 00:38:41 +01:00
|
|
|
}
|
2014-07-13 04:47:31 +02:00
|
|
|
}
|
2014-12-06 00:38:41 +01:00
|
|
|
} else {
|
2017-01-19 05:50:45 +01:00
|
|
|
// Get the state
|
terraform: Ugly huge change to weave in new State and Plan types
Due to how often the state and plan types are referenced throughout
Terraform, there isn't a great way to switch them out gradually. As a
consequence, this huge commit gets us from the old world to a _compilable_
new world, but still has a large number of known test failures due to
key functionality being stubbed out.
The stubs here are for anything that interacts with providers, since we
now need to do the follow-up work to similarly replace the old
terraform.ResourceProvider interface with its replacement in the new
"providers" package. That work, along with work to fix the remaining
failing tests, will follow in subsequent commits.
The aim here was to replace all references to terraform.State and its
downstream types with states.State, terraform.Plan with plans.Plan,
state.State with statemgr.State, and switch to the new implementations of
the state and plan file formats. However, due to the number of times those
types are used, this also ended up affecting numerous other parts of core
such as terraform.Hook, the backend.Backend interface, and most of the CLI
commands.
Just as with 5861dbf3fc49b19587a31816eb06f511ab861bb4 before, I apologize
in advance to the person who inevitably just found this huge commit while
spelunking through the commit history.
2018-08-14 23:24:45 +02:00
|
|
|
stateStore, err := b.StateMgr(env)
|
2017-01-19 05:50:45 +01:00
|
|
|
if err != nil {
|
|
|
|
c.Ui.Error(fmt.Sprintf("Failed to load state: %s", err))
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := stateStore.RefreshState(); err != nil {
|
|
|
|
c.Ui.Error(fmt.Sprintf("Failed to load state: %s", err))
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
state = stateStore.State()
|
2014-12-06 00:38:41 +01:00
|
|
|
if state == nil {
|
|
|
|
c.Ui.Output("No state.")
|
|
|
|
return 0
|
2014-07-13 04:47:31 +02:00
|
|
|
}
|
|
|
|
}
|
2014-12-06 00:38:41 +01:00
|
|
|
|
2014-07-13 04:47:31 +02:00
|
|
|
if plan == nil && state == nil {
|
|
|
|
c.Ui.Error(fmt.Sprintf(
|
|
|
|
"Terraform couldn't read the given file as a state or plan file.\n"+
|
|
|
|
"The errors while attempting to read the file as each format are\n"+
|
|
|
|
"shown below.\n\n"+
|
|
|
|
"State read error: %s\n\nPlan read error: %s",
|
|
|
|
stateErr,
|
|
|
|
planErr))
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
if plan != nil {
|
terraform: Ugly huge change to weave in new State and Plan types
Due to how often the state and plan types are referenced throughout
Terraform, there isn't a great way to switch them out gradually. As a
consequence, this huge commit gets us from the old world to a _compilable_
new world, but still has a large number of known test failures due to
key functionality being stubbed out.
The stubs here are for anything that interacts with providers, since we
now need to do the follow-up work to similarly replace the old
terraform.ResourceProvider interface with its replacement in the new
"providers" package. That work, along with work to fix the remaining
failing tests, will follow in subsequent commits.
The aim here was to replace all references to terraform.State and its
downstream types with states.State, terraform.Plan with plans.Plan,
state.State with statemgr.State, and switch to the new implementations of
the state and plan file formats. However, due to the number of times those
types are used, this also ended up affecting numerous other parts of core
such as terraform.Hook, the backend.Backend interface, and most of the CLI
commands.
Just as with 5861dbf3fc49b19587a31816eb06f511ab861bb4 before, I apologize
in advance to the person who inevitably just found this huge commit while
spelunking through the commit history.
2018-08-14 23:24:45 +02:00
|
|
|
dispPlan := format.NewPlan(plan.Changes)
|
command/format: improve consistency of plan results
Previously the rendered plan output was constructed directly from the
core plan and then annotated with counts derived from the count hook.
At various places we applied little adjustments to deal with the fact that
the user-facing diff model is not identical to the internal diff model,
including the special handling of data source reads and destroys. Since
this logic was just muddled into the rendering code, it behaved
inconsistently with the tally of adds, updates and deletes.
This change reworks the plan formatter so that it happens in two stages:
- First, we produce a specialized Plan object that is tailored for use
in the UI. This applies all the relevant logic to transform the
physical model into the user model.
- Second, we do a straightforward visual rendering of the display-oriented
plan object.
For the moment this is slightly overkill since there's only one rendering
path, but it does give us the benefit of letting the counts be derived
from the same data as the full detailed diff, ensuring that they'll stay
consistent.
Later we may choose to have other UIs for plans, such as a
machine-readable output intended to drive a web UI. In that case, we'd
want the web UI to consume a serialization of the _display-oriented_ plan
so that it doesn't need to re-implement all of these UI special cases.
This introduces to core a new diff action type for "refresh". Currently
this is used _only_ in the UI layer, to represent data source reads.
Later it would be good to use this type for the core diff as well, to
improve consistency, but that is left for another day to keep this change
focused on the UI.
2017-08-24 01:23:02 +02:00
|
|
|
c.Ui.Output(dispPlan.Format(c.Colorize()))
|
2014-07-13 04:47:31 +02:00
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
2017-01-19 05:50:45 +01:00
|
|
|
c.Ui.Output(format.State(&format.StateOpts{
|
2018-09-25 00:00:07 +02:00
|
|
|
State: state,
|
|
|
|
Color: c.Colorize(),
|
|
|
|
Schemas: schemas,
|
2014-09-26 04:25:10 +02:00
|
|
|
}))
|
2014-07-13 04:47:31 +02:00
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *ShowCommand) Help() string {
|
|
|
|
helpText := `
|
2014-10-11 21:57:47 +02:00
|
|
|
Usage: terraform show [options] [path]
|
2014-07-13 04:47:31 +02:00
|
|
|
|
|
|
|
Reads and outputs a Terraform state or plan file in a human-readable
|
2014-10-11 21:57:47 +02:00
|
|
|
form. If no path is specified, the current state will be shown.
|
2014-07-13 04:47:31 +02:00
|
|
|
|
2014-07-13 05:21:46 +02:00
|
|
|
Options:
|
|
|
|
|
2014-09-26 04:25:10 +02:00
|
|
|
-no-color If specified, output won't contain any color.
|
2014-07-13 05:21:46 +02:00
|
|
|
|
2014-07-13 04:47:31 +02:00
|
|
|
`
|
|
|
|
return strings.TrimSpace(helpText)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *ShowCommand) Synopsis() string {
|
|
|
|
return "Inspect Terraform state or plan"
|
|
|
|
}
|