Skip to content

Commit 9fb91c2

Browse files
authored
PSS: Refactor Plan struct to reference Backend and StateStore via pointers, update calling code (#37946)
* refactor: Update Plan struct's Backend field to be a pointer * fix: Add some refactorings or protections against nil pointers when accessing the Backend field on a Plan struct * refactor: Update Plan struct's StateStore field to be a pointer, update a nil check in calling code.
1 parent 64015ca commit 9fb91c2

File tree

12 files changed

+33
-29
lines changed

12 files changed

+33
-29
lines changed

internal/backend/local/backend_local_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ func TestLocalRun_stalePlan(t *testing.T) {
160160
plan := &plans.Plan{
161161
UIMode: plans.NormalMode,
162162
Changes: plans.NewChangesSrc(),
163-
Backend: plans.Backend{
163+
Backend: &plans.Backend{
164164
Type: "local",
165165
Config: backendConfigRaw,
166166
},

internal/backend/local/backend_plan.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ func (b *Local) opPlan(
158158
op.ReportResult(runningOp, diags)
159159
return
160160
}
161-
plan.Backend = *op.PlanOutBackend
161+
plan.Backend = op.PlanOutBackend
162162

163163
// We may have updated the state in the refresh step above, but we
164164
// will freeze that updated state in the plan file for now and

internal/command/apply.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ func (c *ApplyCommand) PrepareBackend(planFile *planfile.WrappedPlanFile, args *
210210
))
211211
return nil, diags
212212
}
213-
if plan.Backend.Config == nil {
213+
if plan.Backend == nil {
214214
// Should never happen; always indicates a bug in the creation of the plan file
215215
diags = diags.Append(tfdiags.Sourceless(
216216
tfdiags.Error,
@@ -220,7 +220,7 @@ func (c *ApplyCommand) PrepareBackend(planFile *planfile.WrappedPlanFile, args *
220220
return nil, diags
221221
}
222222
// TODO: Update BackendForLocalPlan to use state storage, and plan to be able to contain State Store config details
223-
be, beDiags = c.BackendForLocalPlan(plan.Backend)
223+
be, beDiags = c.BackendForLocalPlan(*plan.Backend)
224224
} else {
225225

226226
// Load the backend

internal/command/apply_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -821,7 +821,7 @@ func TestApply_plan_remoteState(t *testing.T) {
821821
t.Fatal(err)
822822
}
823823
planPath := testPlanFile(t, snap, state, &plans.Plan{
824-
Backend: plans.Backend{
824+
Backend: &plans.Backend{
825825
Type: "http",
826826
Config: backendConfigRaw,
827827
},

internal/command/command_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ func testPlan(t *testing.T) *plans.Plan {
188188
}
189189

190190
return &plans.Plan{
191-
Backend: plans.Backend{
191+
Backend: &plans.Backend{
192192
// This is just a placeholder so that the plan file can be written
193193
// out. Caller may wish to override it to something more "real"
194194
// where the plan will actually be subsequently applied.

internal/command/graph_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ func TestGraph_applyPhaseSavedPlan(t *testing.T) {
325325
},
326326
})
327327

328-
plan.Backend = plans.Backend{
328+
plan.Backend = &plans.Backend{
329329
// Doesn't actually matter since we aren't going to activate the backend
330330
// for this command anyway, but we need something here for the plan
331331
// file writer to succeed.

internal/command/plan_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,9 @@ func TestPlan_outBackend(t *testing.T) {
447447
t.Fatalf("Expected empty plan to be written to plan file, got: %s", spew.Sdump(plan))
448448
}
449449

450+
if plan.Backend == nil {
451+
t.Fatal("unexpected nil Backend")
452+
}
450453
if got, want := plan.Backend.Type, "http"; got != want {
451454
t.Errorf("wrong backend type %q; want %q", got, want)
452455
}

internal/plans/plan.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ type Plan struct {
7474
ActionTargetAddrs []addrs.Targetable
7575
ForceReplaceAddrs []addrs.AbsResourceInstance
7676

77-
Backend Backend
78-
StateStore StateStore
77+
Backend *Backend
78+
StateStore *StateStore
7979

8080
// Complete is true if Terraform considers this to be a "complete" plan,
8181
// which is to say that it includes a planned action (even if no-op)

internal/plans/planfile/planfile_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ func TestRoundtrip(t *testing.T) {
6363
VariableValues: map[string]plans.DynamicValue{
6464
"foo": plans.DynamicValue([]byte("foo placeholder")),
6565
},
66-
Backend: plans.Backend{
66+
Backend: &plans.Backend{
6767
Type: "local",
6868
Config: plans.DynamicValue([]byte("config placeholder")),
6969
Workspace: "default",

internal/plans/planfile/tfplan.go

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ func readTfplan(r io.Reader) (*plans.Plan, error) {
222222
if err != nil {
223223
return nil, fmt.Errorf("plan file has invalid backend configuration: %s", err)
224224
}
225-
plan.Backend = plans.Backend{
225+
plan.Backend = &plans.Backend{
226226
Type: rawBackend.Type,
227227
Config: config,
228228
Workspace: rawBackend.Workspace,
@@ -243,7 +243,7 @@ func readTfplan(r io.Reader) (*plans.Plan, error) {
243243
return nil, fmt.Errorf("plan file has invalid state_store provider version: %s", err)
244244
}
245245

246-
plan.StateStore = plans.StateStore{
246+
plan.StateStore = &plans.StateStore{
247247
Type: rawStateStore.Type,
248248
Provider: provider,
249249
Config: config,
@@ -737,25 +737,23 @@ func writeTfplan(plan *plans.Plan, w io.Writer) error {
737737
}
738738

739739
// Store details about accessing state
740-
backendInUse := plan.Backend.Type != "" && plan.Backend.Config != nil
741-
stateStoreInUse := plan.StateStore.Type != "" && plan.StateStore.Config != nil
742740
switch {
743-
case !backendInUse && !stateStoreInUse:
741+
case plan.Backend == nil && plan.StateStore == nil:
744742
// This suggests a bug in the code that created the plan, since it
745743
// ought to always have either a backend or state_store populated, even if it's the default
746744
// "local" backend with a local state file.
747745
return fmt.Errorf("plan does not have a backend or state_store configuration")
748-
case backendInUse && stateStoreInUse:
746+
case plan.Backend != nil && plan.StateStore != nil:
749747
// This suggests a bug in the code that created the plan, since it
750748
// should never have both a backend and state_store populated.
751749
return fmt.Errorf("plan contains both backend and state_store configurations, only one is expected")
752-
case backendInUse:
750+
case plan.Backend != nil:
753751
rawPlan.Backend = &planproto.Backend{
754752
Type: plan.Backend.Type,
755753
Config: valueToTfplan(plan.Backend.Config),
756754
Workspace: plan.Backend.Workspace,
757755
}
758-
case stateStoreInUse:
756+
case plan.StateStore != nil:
759757
rawPlan.StateStore = &planproto.StateStore{
760758
Type: plan.StateStore.Type,
761759
Provider: &planproto.Provider{

0 commit comments

Comments
 (0)