Merge pull request #30205 from hashicorp/alisdair/fix-show-plan-against-non-default-state
command/show: Disable plan state lineage checks
This commit is contained in:
commit
535da4ebc7
|
@ -275,6 +275,13 @@ type Operation struct {
|
|||
// the variables set in the plan are used instead, and they must be valid.
|
||||
AllowUnsetVariables bool
|
||||
|
||||
// When loading a plan file for a read-only operation, we may want to
|
||||
// disable the state lineage checks which are only relevant for operations
|
||||
// which can modify state. An example where this is important is showing
|
||||
// a plan which was prepared against a non-default state file, because the
|
||||
// lineage checks are always against the default state.
|
||||
DisablePlanFileStateLineageChecks bool
|
||||
|
||||
// View implements the logic for all UI interactions.
|
||||
View views.Operation
|
||||
|
||||
|
|
|
@ -284,7 +284,7 @@ func (b *Local) localRunForPlanFile(op *backend.Operation, pf *planfile.Reader,
|
|||
))
|
||||
return nil, snap, diags
|
||||
}
|
||||
if currentStateMeta != nil {
|
||||
if !op.DisablePlanFileStateLineageChecks && currentStateMeta != nil {
|
||||
// If the caller sets this, we require that the stored prior state
|
||||
// has the same metadata, which is an extra safety check that nothing
|
||||
// has changed since the plan was created. (All of the "real-world"
|
||||
|
|
|
@ -94,6 +94,7 @@ func (c *ShowCommand) Run(args []string) int {
|
|||
opReq.PlanFile = planFile
|
||||
opReq.ConfigLoader, err = c.initConfigLoader()
|
||||
opReq.AllowUnsetVariables = true
|
||||
opReq.DisablePlanFileStateLineageChecks = true
|
||||
if err != nil {
|
||||
diags = diags.Append(err)
|
||||
c.showDiagnostics(diags)
|
||||
|
|
|
@ -15,7 +15,9 @@ import (
|
|||
"github.com/hashicorp/terraform/internal/plans"
|
||||
"github.com/hashicorp/terraform/internal/providers"
|
||||
"github.com/hashicorp/terraform/internal/states"
|
||||
"github.com/hashicorp/terraform/internal/states/statemgr"
|
||||
"github.com/hashicorp/terraform/internal/terraform"
|
||||
"github.com/hashicorp/terraform/version"
|
||||
"github.com/mitchellh/cli"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
)
|
||||
|
@ -575,6 +577,52 @@ func TestShow_json_output_state(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestShow_planWithNonDefaultStateLineage(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("show"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
// Write default state file with a testing lineage ("fake-for-testing")
|
||||
testStateFileDefault(t, testState())
|
||||
|
||||
// Create a plan with a different lineage, which we should still be able
|
||||
// to show
|
||||
_, snap := testModuleWithSnapshot(t, "show")
|
||||
state := testState()
|
||||
plan := testPlan(t)
|
||||
stateMeta := statemgr.SnapshotMeta{
|
||||
Lineage: "fake-for-plan",
|
||||
Serial: 1,
|
||||
TerraformVersion: version.SemVer,
|
||||
}
|
||||
planPath := testPlanFileMatchState(t, snap, state, plan, stateMeta)
|
||||
|
||||
ui := cli.NewMockUi()
|
||||
view, done := testView(t)
|
||||
c := &ShowCommand{
|
||||
Meta: Meta{
|
||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||
Ui: ui,
|
||||
View: view,
|
||||
},
|
||||
}
|
||||
|
||||
args := []string{
|
||||
planPath,
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
|
||||
}
|
||||
|
||||
want := `No changes. Your infrastructure matches the configuration.`
|
||||
got := done(t).Stdout()
|
||||
if !strings.Contains(got, want) {
|
||||
t.Errorf("missing expected output\nwant: %s\ngot:\n%s", want, got)
|
||||
}
|
||||
}
|
||||
|
||||
// showFixtureSchema returns a schema suitable for processing the configuration
|
||||
// in testdata/show. This schema should be assigned to a mock provider
|
||||
// named "test".
|
||||
|
|
Loading…
Reference in New Issue