Skip to content

Commit 30d9b69

Browse files
committed
backport changes from cloud package to remote package
1 parent 45da988 commit 30d9b69

File tree

7 files changed

+83
-65
lines changed

7 files changed

+83
-65
lines changed

internal/backend/remote/backend.go

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -673,19 +673,14 @@ func (b *Remote) StateMgr(name string) (statemgr.Full, error) {
673673
return &remote.State{Client: client}, nil
674674
}
675675

676-
// Operation implements backend.Enhanced.
677-
func (b *Remote) Operation(ctx context.Context, op *backend.Operation) (*backend.RunningOperation, error) {
678-
// Get the remote workspace name.
679-
name := op.Workspace
680-
switch {
681-
case op.Workspace == backend.DefaultStateName:
682-
name = b.workspace
683-
case b.prefix != "" && !strings.HasPrefix(op.Workspace, b.prefix):
684-
name = b.prefix + op.Workspace
685-
}
676+
func isLocalExecutionMode(execMode string) bool {
677+
return execMode == "local"
678+
}
686679

680+
func (b *Remote) fetchWorkspace(ctx context.Context, organization string, name string) (*tfe.Workspace, error) {
681+
remoteWorkspaceName := b.getRemoteWorkspaceName(name)
687682
// Retrieve the workspace for this operation.
688-
w, err := b.client.Workspaces.Read(ctx, b.organization, name)
683+
w, err := b.client.Workspaces.Read(ctx, b.organization, remoteWorkspaceName)
689684
if err != nil {
690685
switch err {
691686
case context.Canceled:
@@ -695,17 +690,29 @@ func (b *Remote) Operation(ctx context.Context, op *backend.Operation) (*backend
695690
"workspace %s not found\n\n"+
696691
"The configured \"remote\" backend returns '404 Not Found' errors for resources\n"+
697692
"that do not exist, as well as for resources that a user doesn't have access\n"+
698-
"to. If the resource does exist, please check the rights for the used token.",
693+
"to. If the resource does exist, please check the rights for the used token",
699694
name,
700695
)
701696
default:
702-
return nil, fmt.Errorf(
703-
"The configured \"remote\" backend encountered an unexpected error:\n\n%s",
697+
err := fmt.Errorf(
698+
"the configured \"remote\" backend encountered an unexpected error:\n\n%s",
704699
err,
705700
)
701+
return nil, err
706702
}
707703
}
708704

705+
return w, nil
706+
}
707+
708+
// Operation implements backend.Enhanced.
709+
func (b *Remote) Operation(ctx context.Context, op *backend.Operation) (*backend.RunningOperation, error) {
710+
w, err := b.fetchWorkspace(ctx, b.organization, op.Workspace)
711+
712+
if err != nil {
713+
return nil, err
714+
}
715+
709716
// Terraform remote version conflicts are not a concern for operations. We
710717
// are in one of three states:
711718
//
@@ -718,7 +725,7 @@ func (b *Remote) Operation(ctx context.Context, op *backend.Operation) (*backend
718725
b.IgnoreVersionConflict()
719726

720727
// Check if we need to use the local backend to run the operation.
721-
if b.forceLocal || !w.Operations {
728+
if b.forceLocal || isLocalExecutionMode(w.ExecutionMode) {
722729
// Record that we're forced to run operations locally to allow the
723730
// command package UI to operate correctly
724731
b.forceLocal = true
@@ -902,7 +909,7 @@ func (b *Remote) VerifyWorkspaceTerraformVersion(workspaceName string) tfdiags.D
902909

903910
// If the workspace has remote operations disabled, the remote Terraform
904911
// version is effectively meaningless, so we'll skip version verification.
905-
if !workspace.Operations {
912+
if isLocalExecutionMode(workspace.ExecutionMode) {
906913
return nil
907914
}
908915

internal/backend/remote/backend_apply_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1526,36 +1526,36 @@ func TestRemote_applyVersionCheck(t *testing.T) {
15261526
localVersion string
15271527
remoteVersion string
15281528
forceLocal bool
1529-
hasOperations bool
1529+
executionMode string
15301530
wantErr string
15311531
}{
15321532
"versions can be different for remote apply": {
15331533
localVersion: "0.14.0",
15341534
remoteVersion: "0.13.5",
1535-
hasOperations: true,
1535+
executionMode: "remote",
15361536
},
15371537
"versions can be different for local apply": {
15381538
localVersion: "0.14.0",
15391539
remoteVersion: "0.13.5",
1540-
hasOperations: false,
1540+
executionMode: "local",
15411541
},
15421542
"force local with remote operations and different versions is acceptable": {
15431543
localVersion: "0.14.0",
15441544
remoteVersion: "0.14.0-acme-provider-bundle",
15451545
forceLocal: true,
1546-
hasOperations: true,
1546+
executionMode: "remote",
15471547
},
15481548
"no error if versions are identical": {
15491549
localVersion: "0.14.0",
15501550
remoteVersion: "0.14.0",
15511551
forceLocal: true,
1552-
hasOperations: true,
1552+
executionMode: "remote",
15531553
},
15541554
"no error if force local but workspace has remote operations disabled": {
15551555
localVersion: "0.14.0",
15561556
remoteVersion: "0.13.5",
15571557
forceLocal: true,
1558-
hasOperations: false,
1558+
executionMode: "local",
15591559
},
15601560
}
15611561

@@ -1591,7 +1591,7 @@ func TestRemote_applyVersionCheck(t *testing.T) {
15911591
b.organization,
15921592
b.workspace,
15931593
tfe.WorkspaceUpdateOptions{
1594-
Operations: tfe.Bool(tc.hasOperations),
1594+
ExecutionMode: tfe.String(tc.executionMode),
15951595
TerraformVersion: tfe.String(tc.remoteVersion),
15961596
},
15971597
)
@@ -1644,7 +1644,7 @@ func TestRemote_applyVersionCheck(t *testing.T) {
16441644
hasRemote := strings.Contains(output, "Running apply in the remote backend")
16451645
hasSummary := strings.Contains(output, "1 added, 0 changed, 0 destroyed")
16461646
hasResources := run.State.HasManagedResourceInstanceObjects()
1647-
if !tc.forceLocal && tc.hasOperations {
1647+
if !tc.forceLocal && !isLocalExecutionMode(tc.executionMode) {
16481648
if !hasRemote {
16491649
t.Errorf("missing remote backend header in output: %s", output)
16501650
}

internal/backend/remote/backend_context.go

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -82,38 +82,47 @@ func (b *Remote) LocalRun(op *backend.Operation) (*backend.LocalRun, statemgr.Fu
8282
}
8383
ret.Config = config
8484

85-
// The underlying API expects us to use the opaque workspace id to request
86-
// variables, so we'll need to look that up using our organization name
87-
// and workspace name.
88-
remoteWorkspaceID, err := b.getRemoteWorkspaceID(context.Background(), op.Workspace)
89-
if err != nil {
90-
diags = diags.Append(fmt.Errorf("error finding remote workspace: %w", err))
91-
return nil, nil, diags
92-
}
93-
94-
log.Printf("[TRACE] backend/remote: retrieving variables from workspace %s/%s (%s)", remoteWorkspaceName, b.organization, remoteWorkspaceID)
95-
tfeVariables, err := b.client.Variables.List(context.Background(), remoteWorkspaceID, tfe.VariableListOptions{})
96-
if err != nil && err != tfe.ErrResourceNotFound {
97-
diags = diags.Append(fmt.Errorf("error loading variables: %w", err))
98-
return nil, nil, diags
99-
}
100-
10185
if op.AllowUnsetVariables {
10286
// If we're not going to use the variables in an operation we'll be
10387
// more lax about them, stubbing out any unset ones as unknown.
10488
// This gives us enough information to produce a consistent context,
10589
// but not enough information to run a real operation (plan, apply, etc)
10690
ret.PlanOpts.SetVariables = stubAllVariables(op.Variables, config.Module.Variables)
10791
} else {
108-
if tfeVariables != nil {
109-
if op.Variables == nil {
110-
op.Variables = make(map[string]backend.UnparsedVariableValue)
92+
// The underlying API expects us to use the opaque workspace id to request
93+
// variables, so we'll need to look that up using our organization name
94+
// and workspace name.
95+
remoteWorkspaceID, err := b.getRemoteWorkspaceID(context.Background(), op.Workspace)
96+
if err != nil {
97+
diags = diags.Append(fmt.Errorf("error finding remote workspace: %w", err))
98+
return nil, nil, diags
99+
}
100+
101+
w, err := b.fetchWorkspace(context.Background(), b.organization, op.Workspace)
102+
if err != nil {
103+
diags = diags.Append(fmt.Errorf("error loading workspace: %w", err))
104+
return nil, nil, diags
105+
}
106+
107+
if isLocalExecutionMode(w.ExecutionMode) {
108+
log.Printf("[TRACE] skipping retrieving variables from workspace %s/%s (%s), workspace is in Local Execution mode", remoteWorkspaceName, b.organization, remoteWorkspaceID)
109+
} else {
110+
log.Printf("[TRACE] backend/remote: retrieving variables from workspace %s/%s (%s)", remoteWorkspaceName, b.organization, remoteWorkspaceID)
111+
tfeVariables, err := b.client.Variables.List(context.Background(), remoteWorkspaceID, tfe.VariableListOptions{})
112+
if err != nil && err != tfe.ErrResourceNotFound {
113+
diags = diags.Append(fmt.Errorf("error loading variables: %w", err))
114+
return nil, nil, diags
111115
}
112-
for _, v := range tfeVariables.Items {
113-
if v.Category == tfe.CategoryTerraform {
114-
if _, ok := op.Variables[v.Key]; !ok {
115-
op.Variables[v.Key] = &remoteStoredVariableValue{
116-
definition: v,
116+
if tfeVariables != nil {
117+
if op.Variables == nil {
118+
op.Variables = make(map[string]backend.UnparsedVariableValue)
119+
}
120+
for _, v := range tfeVariables.Items {
121+
if v.Category == tfe.CategoryTerraform {
122+
if _, ok := op.Variables[v.Key]; !ok {
123+
op.Variables[v.Key] = &remoteStoredVariableValue{
124+
definition: v,
125+
}
117126
}
118127
}
119128
}

internal/backend/remote/backend_plan_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1241,7 +1241,7 @@ func TestRemote_planOtherError(t *testing.T) {
12411241
}
12421242

12431243
if !strings.Contains(err.Error(),
1244-
"The configured \"remote\" backend encountered an unexpected error:\n\nI'm a little teacup") {
1244+
"the configured \"remote\" backend encountered an unexpected error:\n\nI'm a little teacup") {
12451245
t.Fatalf("expected error message, got: %s", err.Error())
12461246
}
12471247
}

internal/backend/remote/backend_test.go

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -556,21 +556,21 @@ func TestRemote_StateMgr_versionCheckLatest(t *testing.T) {
556556

557557
func TestRemote_VerifyWorkspaceTerraformVersion(t *testing.T) {
558558
testCases := []struct {
559-
local string
560-
remote string
561-
operations bool
562-
wantErr bool
559+
local string
560+
remote string
561+
executionMode string
562+
wantErr bool
563563
}{
564-
{"0.13.5", "0.13.5", true, false},
565-
{"0.14.0", "0.13.5", true, true},
566-
{"0.14.0", "0.13.5", false, false},
567-
{"0.14.0", "0.14.1", true, false},
568-
{"0.14.0", "1.0.99", true, false},
569-
{"0.14.0", "1.1.0", true, false},
570-
{"0.14.0", "1.2.0", true, true},
571-
{"1.2.0", "1.2.99", true, false},
572-
{"1.2.0", "1.3.0", true, true},
573-
{"0.15.0", "latest", true, false},
564+
{"0.13.5", "0.13.5", "remote", false},
565+
{"0.14.0", "0.13.5", "remote", true},
566+
{"0.14.0", "0.13.5", "local", false},
567+
{"0.14.0", "0.14.1", "remote", false},
568+
{"0.14.0", "1.0.99", "remote", false},
569+
{"0.14.0", "1.1.0", "remote", false},
570+
{"0.14.0", "1.2.0", "remote", true},
571+
{"1.2.0", "1.2.99", "remote", false},
572+
{"1.2.0", "1.3.0", "remote", true},
573+
{"0.15.0", "latest", "remote", false},
574574
}
575575
for _, tc := range testCases {
576576
t.Run(fmt.Sprintf("local %s, remote %s", tc.local, tc.remote), func(t *testing.T) {
@@ -601,7 +601,7 @@ func TestRemote_VerifyWorkspaceTerraformVersion(t *testing.T) {
601601
b.organization,
602602
b.workspace,
603603
tfe.WorkspaceUpdateOptions{
604-
Operations: tfe.Bool(tc.operations),
604+
ExecutionMode: &tc.executionMode,
605605
TerraformVersion: tfe.String(tc.remote),
606606
},
607607
); err != nil {

internal/cloud/backend_context.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ package cloud
33
import (
44
"context"
55
"fmt"
6-
"github.com/hashicorp/hcl/v2"
76
"log"
87

8+
"github.com/hashicorp/hcl/v2"
9+
910
tfe "github.com/hashicorp/go-tfe"
1011
"github.com/hashicorp/hcl/v2/hclsyntax"
1112
"github.com/hashicorp/terraform/internal/backend"
@@ -117,6 +118,7 @@ func (b *Cloud) LocalRun(op *backend.Operation) (*backend.LocalRun, statemgr.Ful
117118
if op.Variables == nil {
118119
op.Variables = make(map[string]backend.UnparsedVariableValue)
119120
}
121+
120122
for _, v := range tfeVariables.Items {
121123
if v.Category == tfe.CategoryTerraform {
122124
if _, ok := op.Variables[v.Key]; !ok {

test.txt

Whitespace-only changes.

0 commit comments

Comments
 (0)