Refactor private workspace fields into workspaceMapping

A mostly cosemetic change; The fields 'workspace' and 'prefix' don't
really describe well what they are from a caller, so change these to use
a workspaceMapping struct to convey they are for implementing workspace
mapping strategies from CLI -> TFC
This commit is contained in:
Chris Arcand 2021-09-07 15:54:33 -05:00
parent 0a125c0400
commit 922a8e4488
6 changed files with 55 additions and 52 deletions

View File

@ -63,12 +63,9 @@ type Cloud struct {
// organization is the organization that contains the target workspaces. // organization is the organization that contains the target workspaces.
organization string organization string
// workspace is used to map the default workspace to a TFC workspace. // workspaceMapping contains strategies for mapping CLI workspaces in the working directory
workspace string // to remote Terraform Cloud workspaces.
workspaceMapping workspaceMapping
// prefix is used to filter down a set of workspaces that use a single
// configuration.
prefix string
// services is used for service discovery // services is used for service discovery
services *disco.Disco services *disco.Disco
@ -183,6 +180,7 @@ func (b *Cloud) Configure(obj cty.Value) tfdiags.Diagnostics {
if obj.IsNull() { if obj.IsNull() {
return diags return diags
} }
diagErr := b.setConfigurationFields(obj) diagErr := b.setConfigurationFields(obj)
if diagErr.HasErrors() { if diagErr.HasErrors() {
return diagErr return diagErr
@ -326,10 +324,10 @@ func (b *Cloud) setConfigurationFields(obj cty.Value) tfdiags.Diagnostics {
// PrepareConfig checks that you cannot set both of these. // PrepareConfig checks that you cannot set both of these.
if val := workspaces.GetAttr("name"); !val.IsNull() { if val := workspaces.GetAttr("name"); !val.IsNull() {
b.workspace = val.AsString() b.workspaceMapping.name = val.AsString()
} }
if val := workspaces.GetAttr("prefix"); !val.IsNull() { if val := workspaces.GetAttr("prefix"); !val.IsNull() {
b.prefix = val.AsString() b.workspaceMapping.prefix = val.AsString()
} }
} }
@ -514,7 +512,7 @@ func (b *Cloud) retryLogHook(attemptNum int, resp *http.Response) {
// Workspaces implements backend.Enhanced. // Workspaces implements backend.Enhanced.
func (b *Cloud) Workspaces() ([]string, error) { func (b *Cloud) Workspaces() ([]string, error) {
if b.prefix == "" { if b.workspaceMapping.prefix == "" {
return nil, backend.ErrWorkspacesNotSupported return nil, backend.ErrWorkspacesNotSupported
} }
return b.workspaces() return b.workspaces()
@ -524,10 +522,10 @@ func (b *Cloud) Workspaces() ([]string, error) {
func (b *Cloud) workspaces() ([]string, error) { func (b *Cloud) workspaces() ([]string, error) {
options := tfe.WorkspaceListOptions{} options := tfe.WorkspaceListOptions{}
switch { switch {
case b.workspace != "": case b.workspaceMapping.name != "":
options.Search = tfe.String(b.workspace) options.Search = tfe.String(b.workspaceMapping.name)
case b.prefix != "": case b.workspaceMapping.prefix != "":
options.Search = tfe.String(b.prefix) options.Search = tfe.String(b.workspaceMapping.prefix)
} }
// Create a slice to contain all the names. // Create a slice to contain all the names.
@ -540,12 +538,12 @@ func (b *Cloud) workspaces() ([]string, error) {
} }
for _, w := range wl.Items { for _, w := range wl.Items {
if b.workspace != "" && w.Name == b.workspace { if b.workspaceMapping.name != "" && w.Name == b.workspaceMapping.name {
names = append(names, backend.DefaultStateName) names = append(names, backend.DefaultStateName)
continue continue
} }
if b.prefix != "" && strings.HasPrefix(w.Name, b.prefix) { if b.workspaceMapping.prefix != "" && strings.HasPrefix(w.Name, b.workspaceMapping.prefix) {
names = append(names, strings.TrimPrefix(w.Name, b.prefix)) names = append(names, strings.TrimPrefix(w.Name, b.workspaceMapping.prefix))
} }
} }
@ -566,19 +564,19 @@ func (b *Cloud) workspaces() ([]string, error) {
// DeleteWorkspace implements backend.Enhanced. // DeleteWorkspace implements backend.Enhanced.
func (b *Cloud) DeleteWorkspace(name string) error { func (b *Cloud) DeleteWorkspace(name string) error {
if b.workspace == "" && name == backend.DefaultStateName { if b.workspaceMapping.name == "" && name == backend.DefaultStateName {
return backend.ErrDefaultWorkspaceNotSupported return backend.ErrDefaultWorkspaceNotSupported
} }
if b.prefix == "" && name != backend.DefaultStateName { if b.workspaceMapping.prefix == "" && name != backend.DefaultStateName {
return backend.ErrWorkspacesNotSupported return backend.ErrWorkspacesNotSupported
} }
// Configure the remote workspace name. // Configure the remote workspace name.
switch { switch {
case name == backend.DefaultStateName: case name == backend.DefaultStateName:
name = b.workspace name = b.workspaceMapping.name
case b.prefix != "" && !strings.HasPrefix(name, b.prefix): case b.workspaceMapping.prefix != "" && !strings.HasPrefix(name, b.workspaceMapping.prefix):
name = b.prefix + name name = b.workspaceMapping.prefix + name
} }
client := &remoteClient{ client := &remoteClient{
@ -594,19 +592,19 @@ func (b *Cloud) DeleteWorkspace(name string) error {
// StateMgr implements backend.Enhanced. // StateMgr implements backend.Enhanced.
func (b *Cloud) StateMgr(name string) (statemgr.Full, error) { func (b *Cloud) StateMgr(name string) (statemgr.Full, error) {
if b.workspace == "" && name == backend.DefaultStateName { if b.workspaceMapping.name == "" && name == backend.DefaultStateName {
return nil, backend.ErrDefaultWorkspaceNotSupported return nil, backend.ErrDefaultWorkspaceNotSupported
} }
if b.prefix == "" && name != backend.DefaultStateName { if b.workspaceMapping.prefix == "" && name != backend.DefaultStateName {
return nil, backend.ErrWorkspacesNotSupported return nil, backend.ErrWorkspacesNotSupported
} }
// Configure the remote workspace name. // Configure the remote workspace name.
switch { switch {
case name == backend.DefaultStateName: case name == backend.DefaultStateName:
name = b.workspace name = b.workspaceMapping.name
case b.prefix != "" && !strings.HasPrefix(name, b.prefix): case b.workspaceMapping.prefix != "" && !strings.HasPrefix(name, b.workspaceMapping.prefix):
name = b.prefix + name name = b.workspaceMapping.prefix + name
} }
workspace, err := b.client.Workspaces.Read(context.Background(), b.organization, name) workspace, err := b.client.Workspaces.Read(context.Background(), b.organization, name)
@ -663,9 +661,9 @@ func (b *Cloud) Operation(ctx context.Context, op *backend.Operation) (*backend.
name := op.Workspace name := op.Workspace
switch { switch {
case op.Workspace == backend.DefaultStateName: case op.Workspace == backend.DefaultStateName:
name = b.workspace name = b.workspaceMapping.name
case b.prefix != "" && !strings.HasPrefix(op.Workspace, b.prefix): case b.workspaceMapping.prefix != "" && !strings.HasPrefix(op.Workspace, b.workspaceMapping.prefix):
name = b.prefix + op.Workspace name = b.workspaceMapping.prefix + op.Workspace
} }
// Retrieve the workspace for this operation. // Retrieve the workspace for this operation.
@ -974,6 +972,11 @@ func (b *Cloud) cliColorize() *colorstring.Colorize {
} }
} }
type workspaceMapping struct {
name string
prefix string
}
func generalError(msg string, err error) error { func generalError(msg string, err error) error {
var diags tfdiags.Diagnostics var diags tfdiags.Diagnostics

View File

@ -143,7 +143,7 @@ func TestCloud_applyWithoutPermissions(t *testing.T) {
context.Background(), context.Background(),
b.organization, b.organization,
tfe.WorkspaceCreateOptions{ tfe.WorkspaceCreateOptions{
Name: tfe.String(b.prefix + "prod"), Name: tfe.String(b.workspaceMapping.prefix + "prod"),
}, },
) )
if err != nil { if err != nil {
@ -183,7 +183,7 @@ func TestCloud_applyWithVCS(t *testing.T) {
context.Background(), context.Background(),
b.organization, b.organization,
tfe.WorkspaceCreateOptions{ tfe.WorkspaceCreateOptions{
Name: tfe.String(b.prefix + "prod"), Name: tfe.String(b.workspaceMapping.prefix + "prod"),
VCSRepo: &tfe.VCSRepoOptions{}, VCSRepo: &tfe.VCSRepoOptions{},
}, },
) )
@ -900,7 +900,7 @@ func TestCloud_applyWithAutoApply(t *testing.T) {
b.organization, b.organization,
tfe.WorkspaceCreateOptions{ tfe.WorkspaceCreateOptions{
AutoApply: tfe.Bool(true), AutoApply: tfe.Bool(true),
Name: tfe.String(b.prefix + "prod"), Name: tfe.String(b.workspaceMapping.prefix + "prod"),
}, },
) )
if err != nil { if err != nil {
@ -1015,7 +1015,7 @@ func TestCloud_applyWorkspaceWithoutOperations(t *testing.T) {
ctx, ctx,
b.organization, b.organization,
tfe.WorkspaceCreateOptions{ tfe.WorkspaceCreateOptions{
Name: tfe.String(b.prefix + "no-operations"), Name: tfe.String(b.workspaceMapping.prefix + "no-operations"),
}, },
) )
if err != nil { if err != nil {
@ -1074,7 +1074,7 @@ func TestCloud_applyLockTimeout(t *testing.T) {
ctx := context.Background() ctx := context.Background()
// Retrieve the workspace used to run this operation in. // Retrieve the workspace used to run this operation in.
w, err := b.client.Workspaces.Read(ctx, b.organization, b.workspace) w, err := b.client.Workspaces.Read(ctx, b.organization, b.workspaceMapping.name)
if err != nil { if err != nil {
t.Fatalf("error retrieving workspace: %v", err) t.Fatalf("error retrieving workspace: %v", err)
} }
@ -1434,7 +1434,7 @@ func TestCloud_applyPolicySoftFailAutoApply(t *testing.T) {
b.organization, b.organization,
tfe.WorkspaceCreateOptions{ tfe.WorkspaceCreateOptions{
AutoApply: tfe.Bool(true), AutoApply: tfe.Bool(true),
Name: tfe.String(b.prefix + "prod"), Name: tfe.String(b.workspaceMapping.prefix + "prod"),
}, },
) )
if err != nil { if err != nil {
@ -1583,7 +1583,7 @@ func TestCloud_applyVersionCheck(t *testing.T) {
_, err := b.client.Workspaces.Update( _, err := b.client.Workspaces.Update(
ctx, ctx,
b.organization, b.organization,
b.workspace, b.workspaceMapping.name,
tfe.WorkspaceUpdateOptions{ tfe.WorkspaceUpdateOptions{
Operations: tfe.Bool(tc.hasOperations), Operations: tfe.Bool(tc.hasOperations),
TerraformVersion: tfe.String(tc.remoteVersion), TerraformVersion: tfe.String(tc.remoteVersion),

View File

@ -143,9 +143,9 @@ func (b *Cloud) getRemoteWorkspaceName(localWorkspaceName string) string {
// The default workspace name is a special case, for when the backend // The default workspace name is a special case, for when the backend
// is configured to with to an exact remote workspace rather than with // is configured to with to an exact remote workspace rather than with
// a remote workspace _prefix_. // a remote workspace _prefix_.
return b.workspace return b.workspaceMapping.name
case b.prefix != "" && !strings.HasPrefix(localWorkspaceName, b.prefix): case b.workspaceMapping.prefix != "" && !strings.HasPrefix(localWorkspaceName, b.workspaceMapping.prefix):
return b.prefix + localWorkspaceName return b.workspaceMapping.prefix + localWorkspaceName
default: default:
return localWorkspaceName return localWorkspaceName
} }

View File

@ -161,7 +161,7 @@ func TestCloud_planWithoutPermissions(t *testing.T) {
context.Background(), context.Background(),
b.organization, b.organization,
tfe.WorkspaceCreateOptions{ tfe.WorkspaceCreateOptions{
Name: tfe.String(b.prefix + "prod"), Name: tfe.String(b.workspaceMapping.prefix + "prod"),
}, },
) )
if err != nil { if err != nil {
@ -772,7 +772,7 @@ func TestCloud_planWorkspaceWithoutOperations(t *testing.T) {
ctx, ctx,
b.organization, b.organization,
tfe.WorkspaceCreateOptions{ tfe.WorkspaceCreateOptions{
Name: tfe.String(b.prefix + "no-operations"), Name: tfe.String(b.workspaceMapping.prefix + "no-operations"),
}, },
) )
if err != nil { if err != nil {
@ -818,7 +818,7 @@ func TestCloud_planLockTimeout(t *testing.T) {
ctx := context.Background() ctx := context.Background()
// Retrieve the workspace used to run this operation in. // Retrieve the workspace used to run this operation in.
w, err := b.client.Workspaces.Read(ctx, b.organization, b.workspace) w, err := b.client.Workspaces.Read(ctx, b.organization, b.workspaceMapping.name)
if err != nil { if err != nil {
t.Fatalf("error retrieving workspace: %v", err) t.Fatalf("error retrieving workspace: %v", err)
} }
@ -941,7 +941,7 @@ func TestCloud_planWithWorkingDirectory(t *testing.T) {
} }
// Configure the workspace to use a custom working directory. // Configure the workspace to use a custom working directory.
_, err := b.client.Workspaces.Update(context.Background(), b.organization, b.workspace, options) _, err := b.client.Workspaces.Update(context.Background(), b.organization, b.workspaceMapping.name, options)
if err != nil { if err != nil {
t.Fatalf("error configuring working directory: %v", err) t.Fatalf("error configuring working directory: %v", err)
} }
@ -986,7 +986,7 @@ func TestCloud_planWithWorkingDirectoryFromCurrentPath(t *testing.T) {
} }
// Configure the workspace to use a custom working directory. // Configure the workspace to use a custom working directory.
_, err := b.client.Workspaces.Update(context.Background(), b.organization, b.workspace, options) _, err := b.client.Workspaces.Update(context.Background(), b.organization, b.workspaceMapping.name, options)
if err != nil { if err != nil {
t.Fatalf("error configuring working directory: %v", err) t.Fatalf("error configuring working directory: %v", err)
} }

View File

@ -664,7 +664,7 @@ func TestCloud_StateMgr_versionCheck(t *testing.T) {
if _, err := b.client.Workspaces.Update( if _, err := b.client.Workspaces.Update(
context.Background(), context.Background(),
b.organization, b.organization,
b.workspace, b.workspaceMapping.name,
tfe.WorkspaceUpdateOptions{ tfe.WorkspaceUpdateOptions{
TerraformVersion: tfe.String(v0140.String()), TerraformVersion: tfe.String(v0140.String()),
}, },
@ -681,7 +681,7 @@ func TestCloud_StateMgr_versionCheck(t *testing.T) {
if _, err := b.client.Workspaces.Update( if _, err := b.client.Workspaces.Update(
context.Background(), context.Background(),
b.organization, b.organization,
b.workspace, b.workspaceMapping.name,
tfe.WorkspaceUpdateOptions{ tfe.WorkspaceUpdateOptions{
TerraformVersion: tfe.String(v0135.String()), TerraformVersion: tfe.String(v0135.String()),
}, },
@ -721,7 +721,7 @@ func TestCloud_StateMgr_versionCheckLatest(t *testing.T) {
if _, err := b.client.Workspaces.Update( if _, err := b.client.Workspaces.Update(
context.Background(), context.Background(),
b.organization, b.organization,
b.workspace, b.workspaceMapping.name,
tfe.WorkspaceUpdateOptions{ tfe.WorkspaceUpdateOptions{
TerraformVersion: tfe.String("latest"), TerraformVersion: tfe.String("latest"),
}, },
@ -779,7 +779,7 @@ func TestCloud_VerifyWorkspaceTerraformVersion(t *testing.T) {
if _, err := b.client.Workspaces.Update( if _, err := b.client.Workspaces.Update(
context.Background(), context.Background(),
b.organization, b.organization,
b.workspace, b.workspaceMapping.name,
tfe.WorkspaceUpdateOptions{ tfe.WorkspaceUpdateOptions{
Operations: tfe.Bool(tc.operations), Operations: tfe.Bool(tc.operations),
TerraformVersion: tfe.String(tc.remote), TerraformVersion: tfe.String(tc.remote),
@ -830,7 +830,7 @@ func TestCloud_VerifyWorkspaceTerraformVersion_workspaceErrors(t *testing.T) {
if _, err := b.client.Workspaces.Update( if _, err := b.client.Workspaces.Update(
context.Background(), context.Background(),
b.organization, b.organization,
b.workspace, b.workspaceMapping.name,
tfe.WorkspaceUpdateOptions{ tfe.WorkspaceUpdateOptions{
TerraformVersion: tfe.String("1.0.cheetarah"), TerraformVersion: tfe.String("1.0.cheetarah"),
}, },
@ -878,7 +878,7 @@ func TestCloud_VerifyWorkspaceTerraformVersion_ignoreFlagSet(t *testing.T) {
if _, err := b.client.Workspaces.Update( if _, err := b.client.Workspaces.Update(
context.Background(), context.Background(),
b.organization, b.organization,
b.workspace, b.workspaceMapping.name,
tfe.WorkspaceUpdateOptions{ tfe.WorkspaceUpdateOptions{
TerraformVersion: tfe.String(remote.String()), TerraformVersion: tfe.String(remote.String()),
}, },

View File

@ -161,9 +161,9 @@ func testBackend(t *testing.T, obj cty.Value) (*Cloud, func()) {
} }
// Create the default workspace if required. // Create the default workspace if required.
if b.workspace != "" { if b.workspaceMapping.name != "" {
_, err = b.client.Workspaces.Create(ctx, b.organization, tfe.WorkspaceCreateOptions{ _, err = b.client.Workspaces.Create(ctx, b.organization, tfe.WorkspaceCreateOptions{
Name: tfe.String(b.workspace), Name: tfe.String(b.workspaceMapping.name),
}) })
if err != nil { if err != nil {
t.Fatalf("error: %v", err) t.Fatalf("error: %v", err)