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 <nick.fagerlund@gmail.com>

Co-authored-by: Nick Fagerlund <nick.fagerlund@gmail.com>
This commit is contained in:
Luces Huayhuaca 2021-11-08 07:20:15 -08:00 committed by GitHub
parent 5ac1074c54
commit 4e3218b4d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 46 additions and 36 deletions

View File

@ -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

View File

@ -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)
}

View File

@ -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 {

View File

@ -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
}