From 4e3218b4d5bf107e4d8cf0b942c6266dc64812b5 Mon Sep 17 00:00:00 2001 From: Luces Huayhuaca <21225410+uturunku1@users.noreply.github.com> Date: Mon, 8 Nov 2021 07:20:15 -0800 Subject: [PATCH] cloud: convert uses of worspaces.operations into workspaces.executionMode (#29844) * convert uses of worspaces.operations into workspaces.executionMode The cloud package currently uses a deprecated API on workspaces to determine a workspace's execution mode. Deprecated: Operations (boolean) New hotness: Execution mode (string - "local", "remote", or "agent") More details: https://www.terraform.io/docs/cloud/api/workspaces.html#request-body All uses of Operations field coming from the client (within the cloud package) should be converted to the appropriate ExecutionMode equivalent. Also, we need to update all acknowledgment of operations field on the tests that are testing the behavior of workspaces. Co-authored-by: Nick Fagerlund Co-authored-by: Nick Fagerlund --- internal/cloud/backend.go | 10 +++++-- internal/cloud/backend_apply_test.go | 16 +++++----- internal/cloud/backend_test.go | 44 ++++++++++++++-------------- internal/cloud/tfe_client_mock.go | 12 ++++++-- 4 files changed, 46 insertions(+), 36 deletions(-) diff --git a/internal/cloud/backend.go b/internal/cloud/backend.go index cff9d7e2b..188996177 100644 --- a/internal/cloud/backend.go +++ b/internal/cloud/backend.go @@ -636,7 +636,7 @@ func (b *Cloud) Operation(ctx context.Context, op *backend.Operation) (*backend. b.IgnoreVersionConflict() // Check if we need to use the local backend to run the operation. - if b.forceLocal || !w.Operations { + if b.forceLocal || isLocalExecutionMode(w.ExecutionMode) { // Record that we're forced to run operations locally to allow the // command package UI to operate correctly b.forceLocal = true @@ -825,9 +825,9 @@ func (b *Cloud) VerifyWorkspaceTerraformVersion(workspaceName string) tfdiags.Di return nil } - // If the workspace has remote operations disabled, the remote Terraform + // If the workspace has execution-mode set to local, the remote Terraform // version is effectively meaningless, so we'll skip version verification. - if !workspace.Operations { + if isLocalExecutionMode(workspace.ExecutionMode) { return nil } @@ -965,6 +965,10 @@ func (wm WorkspaceMapping) Strategy() workspaceStrategy { } } +func isLocalExecutionMode(execMode string) bool { + return execMode == "local" +} + func (wm WorkspaceMapping) tfeTags() []*tfe.Tag { var tags []*tfe.Tag diff --git a/internal/cloud/backend_apply_test.go b/internal/cloud/backend_apply_test.go index d741662cd..6c4ea4106 100644 --- a/internal/cloud/backend_apply_test.go +++ b/internal/cloud/backend_apply_test.go @@ -1447,36 +1447,36 @@ func TestCloud_applyVersionCheck(t *testing.T) { localVersion string remoteVersion string forceLocal bool - hasOperations bool + executionMode string wantErr string }{ "versions can be different for remote apply": { localVersion: "0.14.0", remoteVersion: "0.13.5", - hasOperations: true, + executionMode: "remote", }, "versions can be different for local apply": { localVersion: "0.14.0", remoteVersion: "0.13.5", - hasOperations: false, + executionMode: "local", }, "force local with remote operations and different versions is acceptable": { localVersion: "0.14.0", remoteVersion: "0.14.0-acme-provider-bundle", forceLocal: true, - hasOperations: true, + executionMode: "remote", }, "no error if versions are identical": { localVersion: "0.14.0", remoteVersion: "0.14.0", forceLocal: true, - hasOperations: true, + executionMode: "remote", }, "no error if force local but workspace has remote operations disabled": { localVersion: "0.14.0", remoteVersion: "0.13.5", forceLocal: true, - hasOperations: false, + executionMode: "local", }, } @@ -1512,7 +1512,7 @@ func TestCloud_applyVersionCheck(t *testing.T) { b.organization, b.WorkspaceMapping.Name, tfe.WorkspaceUpdateOptions{ - Operations: tfe.Bool(tc.hasOperations), + ExecutionMode: tfe.String(tc.executionMode), TerraformVersion: tfe.String(tc.remoteVersion), }, ) @@ -1566,7 +1566,7 @@ func TestCloud_applyVersionCheck(t *testing.T) { hasRemote := strings.Contains(output, "Running apply in Terraform Cloud") hasSummary := strings.Contains(output, "1 added, 0 changed, 0 destroyed") hasResources := run.State.HasManagedResourceInstanceObjects() - if !tc.forceLocal && tc.hasOperations { + if !tc.forceLocal && !isLocalExecutionMode(tc.executionMode) { if !hasRemote { t.Errorf("missing TFC header in output: %s", output) } diff --git a/internal/cloud/backend_test.go b/internal/cloud/backend_test.go index 3bb9e148d..68e3c4167 100644 --- a/internal/cloud/backend_test.go +++ b/internal/cloud/backend_test.go @@ -680,31 +680,31 @@ func TestCloud_StateMgr_versionCheckLatest(t *testing.T) { func TestCloud_VerifyWorkspaceTerraformVersion(t *testing.T) { testCases := []struct { - local string - remote string - operations bool - wantErr bool + local string + remote string + executionMode string + wantErr bool }{ - {"0.13.5", "0.13.5", true, false}, - {"0.14.0", "0.13.5", true, true}, - {"0.14.0", "0.13.5", false, false}, - {"0.14.0", "0.14.1", true, false}, - {"0.14.0", "1.0.99", true, false}, - {"0.14.0", "1.1.0", true, false}, - {"0.14.0", "1.2.0", true, true}, - {"1.2.0", "1.2.99", true, false}, - {"1.2.0", "1.3.0", true, true}, - {"0.15.0", "latest", true, false}, - {"1.1.5", "~> 1.1.1", true, false}, - {"1.1.5", "> 1.1.0, < 1.3.0", true, false}, - {"1.1.5", "~> 1.0.1", true, true}, + {"0.13.5", "0.13.5", "agent", false}, + {"0.14.0", "0.13.5", "remote", true}, + {"0.14.0", "0.13.5", "local", false}, + {"0.14.0", "0.14.1", "remote", false}, + {"0.14.0", "1.0.99", "remote", false}, + {"0.14.0", "1.1.0", "remote", false}, + {"0.14.0", "1.2.0", "remote", true}, + {"1.2.0", "1.2.99", "remote", false}, + {"1.2.0", "1.3.0", "remote", true}, + {"0.15.0", "latest", "remote", false}, + {"1.1.5", "~> 1.1.1", "remote", false}, + {"1.1.5", "> 1.1.0, < 1.3.0", "remote", false}, + {"1.1.5", "~> 1.0.1", "remote", true}, // pre-release versions are comparable within their pre-release stage (dev, // alpha, beta), but not comparable to different stages and not comparable // to final releases. - {"1.1.0-beta1", "1.1.0-beta1", true, false}, - {"1.1.0-beta1", "~> 1.1.0-beta", true, false}, - {"1.1.0", "~> 1.1.0-beta", true, true}, - {"1.1.0-beta1", "~> 1.1.0-dev", true, true}, + {"1.1.0-beta1", "1.1.0-beta1", "remote", false}, + {"1.1.0-beta1", "~> 1.1.0-beta", "remote", false}, + {"1.1.0", "~> 1.1.0-beta", "remote", true}, + {"1.1.0-beta1", "~> 1.1.0-dev", "remote", true}, } for _, tc := range testCases { t.Run(fmt.Sprintf("local %s, remote %s", tc.local, tc.remote), func(t *testing.T) { @@ -735,7 +735,7 @@ func TestCloud_VerifyWorkspaceTerraformVersion(t *testing.T) { b.organization, b.WorkspaceMapping.Name, tfe.WorkspaceUpdateOptions{ - Operations: tfe.Bool(tc.operations), + ExecutionMode: &tc.executionMode, TerraformVersion: tfe.String(tc.remote), }, ); err != nil { diff --git a/internal/cloud/tfe_client_mock.go b/internal/cloud/tfe_client_mock.go index 929e39b89..2725d8178 100644 --- a/internal/cloud/tfe_client_mock.go +++ b/internal/cloud/tfe_client_mock.go @@ -1165,13 +1165,16 @@ func (m *MockWorkspaces) Create(ctx context.Context, organization string, option } if strings.HasSuffix(*options.Name, "no-operations") { options.Operations = tfe.Bool(false) + options.ExecutionMode = tfe.String("local") } else if options.Operations == nil { options.Operations = tfe.Bool(true) + options.ExecutionMode = tfe.String("remote") } w := &tfe.Workspace{ - ID: GenerateID("ws-"), - Name: *options.Name, - Operations: *options.Operations, + ID: GenerateID("ws-"), + Name: *options.Name, + ExecutionMode: *options.ExecutionMode, + Operations: *options.Operations, Permissions: &tfe.WorkspacePermissions{ CanQueueApply: true, CanQueueRun: true, @@ -1276,6 +1279,9 @@ func updateMockWorkspaceAttributes(w *tfe.Workspace, options tfe.WorkspaceUpdate if options.Operations != nil { w.Operations = *options.Operations } + if options.ExecutionMode != nil { + w.ExecutionMode = *options.ExecutionMode + } if options.Name != nil { w.Name = *options.Name }