diff --git a/tfexec/show.go b/tfexec/show.go index 937e8ccb..b1b153b2 100644 --- a/tfexec/show.go +++ b/tfexec/show.go @@ -10,6 +10,8 @@ import ( tfjson "github.com/hashicorp/terraform-json" ) +// Show reads the default state path and outputs the state. +// To read a state or plan file, ShowState or ShowPlan must be used instead. func (tf *Terraform) Show(ctx context.Context) (*tfjson.State, error) { err := tf.compatible(ctx, tf0_12_0, nil) if err != nil { @@ -40,6 +42,69 @@ func (tf *Terraform) Show(ctx context.Context) (*tfjson.State, error) { return &ret, nil } +// ShowState reads a given state file and outputs the state. +func (tf *Terraform) ShowState(ctx context.Context, statePath string) (*tfjson.State, error) { + err := tf.compatible(ctx, tf0_12_0, nil) + if err != nil { + return nil, fmt.Errorf("terraform show -json was added in 0.12.0: %w", err) + } + + showCmd := tf.showCmd(ctx, statePath) + + var ret tfjson.State + var outBuf bytes.Buffer + showCmd.Stdout = &outBuf + + err = tf.runTerraformCmd(showCmd) + if err != nil { + return nil, err + } + + err = json.Unmarshal(outBuf.Bytes(), &ret) + if err != nil { + return nil, err + } + + err = ret.Validate() + if err != nil { + return nil, err + } + + return &ret, nil +} + +// ShowPlan reads a given plan file and outputs the plan. +func (tf *Terraform) ShowPlan(ctx context.Context, planPath string) (*tfjson.Plan, error) { + err := tf.compatible(ctx, tf0_12_0, nil) + if err != nil { + return nil, fmt.Errorf("terraform show -json was added in 0.12.0: %w", err) + } + + showCmd := tf.showCmd(ctx, planPath) + + var ret tfjson.Plan + var outBuf bytes.Buffer + showCmd.Stdout = &outBuf + + err = tf.runTerraformCmd(showCmd) + if err != nil { + return nil, err + } + + err = json.Unmarshal(outBuf.Bytes(), &ret) + if err != nil { + return nil, err + } + + err = ret.Validate() + if err != nil { + return nil, err + } + + return &ret, nil + +} + func (tf *Terraform) showCmd(ctx context.Context, args ...string) *exec.Cmd { allArgs := []string{"show", "-json", "-no-color"} allArgs = append(allArgs, args...) diff --git a/tfexec/show_test.go b/tfexec/show_test.go index 79fd4b5b..6a470dc2 100644 --- a/tfexec/show_test.go +++ b/tfexec/show_test.go @@ -29,3 +29,47 @@ func TestShowCmd(t *testing.T) { "-no-color", }, nil, showCmd) } + +func TestShowStateCmd(t *testing.T) { + td := testTempDir(t) + defer os.RemoveAll(td) + + tf, err := NewTerraform(td, tfVersion(t, testutil.Latest012)) + if err != nil { + t.Fatal(err) + } + + // empty env, to avoid environ mismatch in testing + tf.SetEnv(map[string]string{}) + + showCmd := tf.showCmd(context.Background(), "statefilepath") + + assertCmd(t, []string{ + "show", + "-json", + "-no-color", + "statefilepath", + }, nil, showCmd) +} + +func TestShowPlanCmd(t *testing.T) { + td := testTempDir(t) + defer os.RemoveAll(td) + + tf, err := NewTerraform(td, tfVersion(t, testutil.Latest012)) + if err != nil { + t.Fatal(err) + } + + // empty env, to avoid environ mismatch in testing + tf.SetEnv(map[string]string{}) + + showCmd := tf.showCmd(context.Background(), "planfilepath") + + assertCmd(t, []string{ + "show", + "-json", + "-no-color", + "planfilepath", + }, nil, showCmd) +}