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 string
// workspace is used to map the default workspace to a TFC workspace.
workspace string
// prefix is used to filter down a set of workspaces that use a single
// configuration.
prefix string
// workspaceMapping contains strategies for mapping CLI workspaces in the working directory
// to remote Terraform Cloud workspaces.
workspaceMapping workspaceMapping
// services is used for service discovery
services *disco.Disco
@ -183,6 +180,7 @@ func (b *Cloud) Configure(obj cty.Value) tfdiags.Diagnostics {
if obj.IsNull() {
return diags
}
diagErr := b.setConfigurationFields(obj)
if diagErr.HasErrors() {
return diagErr
@ -326,10 +324,10 @@ func (b *Cloud) setConfigurationFields(obj cty.Value) tfdiags.Diagnostics {
// PrepareConfig checks that you cannot set both of these.
if val := workspaces.GetAttr("name"); !val.IsNull() {
b.workspace = val.AsString()
b.workspaceMapping.name = val.AsString()
}
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.
func (b *Cloud) Workspaces() ([]string, error) {
if b.prefix == "" {
if b.workspaceMapping.prefix == "" {
return nil, backend.ErrWorkspacesNotSupported
}
return b.workspaces()
@ -524,10 +522,10 @@ func (b *Cloud) Workspaces() ([]string, error) {
func (b *Cloud) workspaces() ([]string, error) {
options := tfe.WorkspaceListOptions{}
switch {
case b.workspace != "":
options.Search = tfe.String(b.workspace)
case b.prefix != "":
options.Search = tfe.String(b.prefix)
case b.workspaceMapping.name != "":
options.Search = tfe.String(b.workspaceMapping.name)
case b.workspaceMapping.prefix != "":
options.Search = tfe.String(b.workspaceMapping.prefix)
}
// Create a slice to contain all the names.
@ -540,12 +538,12 @@ func (b *Cloud) workspaces() ([]string, error) {
}
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)
continue
}
if b.prefix != "" && strings.HasPrefix(w.Name, b.prefix) {
names = append(names, strings.TrimPrefix(w.Name, b.prefix))
if b.workspaceMapping.prefix != "" && strings.HasPrefix(w.Name, b.workspaceMapping.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.
func (b *Cloud) DeleteWorkspace(name string) error {
if b.workspace == "" && name == backend.DefaultStateName {
if b.workspaceMapping.name == "" && name == backend.DefaultStateName {
return backend.ErrDefaultWorkspaceNotSupported
}
if b.prefix == "" && name != backend.DefaultStateName {
if b.workspaceMapping.prefix == "" && name != backend.DefaultStateName {
return backend.ErrWorkspacesNotSupported
}
// Configure the remote workspace name.
switch {
case name == backend.DefaultStateName:
name = b.workspace
case b.prefix != "" && !strings.HasPrefix(name, b.prefix):
name = b.prefix + name
name = b.workspaceMapping.name
case b.workspaceMapping.prefix != "" && !strings.HasPrefix(name, b.workspaceMapping.prefix):
name = b.workspaceMapping.prefix + name
}
client := &remoteClient{
@ -594,19 +592,19 @@ func (b *Cloud) DeleteWorkspace(name string) error {
// StateMgr implements backend.Enhanced.
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
}
if b.prefix == "" && name != backend.DefaultStateName {
if b.workspaceMapping.prefix == "" && name != backend.DefaultStateName {
return nil, backend.ErrWorkspacesNotSupported
}
// Configure the remote workspace name.
switch {
case name == backend.DefaultStateName:
name = b.workspace
case b.prefix != "" && !strings.HasPrefix(name, b.prefix):
name = b.prefix + name
name = b.workspaceMapping.name
case b.workspaceMapping.prefix != "" && !strings.HasPrefix(name, b.workspaceMapping.prefix):
name = b.workspaceMapping.prefix + 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
switch {
case op.Workspace == backend.DefaultStateName:
name = b.workspace
case b.prefix != "" && !strings.HasPrefix(op.Workspace, b.prefix):
name = b.prefix + op.Workspace
name = b.workspaceMapping.name
case b.workspaceMapping.prefix != "" && !strings.HasPrefix(op.Workspace, b.workspaceMapping.prefix):
name = b.workspaceMapping.prefix + op.Workspace
}
// 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 {
var diags tfdiags.Diagnostics

View File

@ -143,7 +143,7 @@ func TestCloud_applyWithoutPermissions(t *testing.T) {
context.Background(),
b.organization,
tfe.WorkspaceCreateOptions{
Name: tfe.String(b.prefix + "prod"),
Name: tfe.String(b.workspaceMapping.prefix + "prod"),
},
)
if err != nil {
@ -183,7 +183,7 @@ func TestCloud_applyWithVCS(t *testing.T) {
context.Background(),
b.organization,
tfe.WorkspaceCreateOptions{
Name: tfe.String(b.prefix + "prod"),
Name: tfe.String(b.workspaceMapping.prefix + "prod"),
VCSRepo: &tfe.VCSRepoOptions{},
},
)
@ -900,7 +900,7 @@ func TestCloud_applyWithAutoApply(t *testing.T) {
b.organization,
tfe.WorkspaceCreateOptions{
AutoApply: tfe.Bool(true),
Name: tfe.String(b.prefix + "prod"),
Name: tfe.String(b.workspaceMapping.prefix + "prod"),
},
)
if err != nil {
@ -1015,7 +1015,7 @@ func TestCloud_applyWorkspaceWithoutOperations(t *testing.T) {
ctx,
b.organization,
tfe.WorkspaceCreateOptions{
Name: tfe.String(b.prefix + "no-operations"),
Name: tfe.String(b.workspaceMapping.prefix + "no-operations"),
},
)
if err != nil {
@ -1074,7 +1074,7 @@ func TestCloud_applyLockTimeout(t *testing.T) {
ctx := context.Background()
// 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 {
t.Fatalf("error retrieving workspace: %v", err)
}
@ -1434,7 +1434,7 @@ func TestCloud_applyPolicySoftFailAutoApply(t *testing.T) {
b.organization,
tfe.WorkspaceCreateOptions{
AutoApply: tfe.Bool(true),
Name: tfe.String(b.prefix + "prod"),
Name: tfe.String(b.workspaceMapping.prefix + "prod"),
},
)
if err != nil {
@ -1583,7 +1583,7 @@ func TestCloud_applyVersionCheck(t *testing.T) {
_, err := b.client.Workspaces.Update(
ctx,
b.organization,
b.workspace,
b.workspaceMapping.name,
tfe.WorkspaceUpdateOptions{
Operations: tfe.Bool(tc.hasOperations),
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
// is configured to with to an exact remote workspace rather than with
// a remote workspace _prefix_.
return b.workspace
case b.prefix != "" && !strings.HasPrefix(localWorkspaceName, b.prefix):
return b.prefix + localWorkspaceName
return b.workspaceMapping.name
case b.workspaceMapping.prefix != "" && !strings.HasPrefix(localWorkspaceName, b.workspaceMapping.prefix):
return b.workspaceMapping.prefix + localWorkspaceName
default:
return localWorkspaceName
}

View File

@ -161,7 +161,7 @@ func TestCloud_planWithoutPermissions(t *testing.T) {
context.Background(),
b.organization,
tfe.WorkspaceCreateOptions{
Name: tfe.String(b.prefix + "prod"),
Name: tfe.String(b.workspaceMapping.prefix + "prod"),
},
)
if err != nil {
@ -772,7 +772,7 @@ func TestCloud_planWorkspaceWithoutOperations(t *testing.T) {
ctx,
b.organization,
tfe.WorkspaceCreateOptions{
Name: tfe.String(b.prefix + "no-operations"),
Name: tfe.String(b.workspaceMapping.prefix + "no-operations"),
},
)
if err != nil {
@ -818,7 +818,7 @@ func TestCloud_planLockTimeout(t *testing.T) {
ctx := context.Background()
// 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 {
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.
_, 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 {
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.
_, 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 {
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(
context.Background(),
b.organization,
b.workspace,
b.workspaceMapping.name,
tfe.WorkspaceUpdateOptions{
TerraformVersion: tfe.String(v0140.String()),
},
@ -681,7 +681,7 @@ func TestCloud_StateMgr_versionCheck(t *testing.T) {
if _, err := b.client.Workspaces.Update(
context.Background(),
b.organization,
b.workspace,
b.workspaceMapping.name,
tfe.WorkspaceUpdateOptions{
TerraformVersion: tfe.String(v0135.String()),
},
@ -721,7 +721,7 @@ func TestCloud_StateMgr_versionCheckLatest(t *testing.T) {
if _, err := b.client.Workspaces.Update(
context.Background(),
b.organization,
b.workspace,
b.workspaceMapping.name,
tfe.WorkspaceUpdateOptions{
TerraformVersion: tfe.String("latest"),
},
@ -779,7 +779,7 @@ func TestCloud_VerifyWorkspaceTerraformVersion(t *testing.T) {
if _, err := b.client.Workspaces.Update(
context.Background(),
b.organization,
b.workspace,
b.workspaceMapping.name,
tfe.WorkspaceUpdateOptions{
Operations: tfe.Bool(tc.operations),
TerraformVersion: tfe.String(tc.remote),
@ -830,7 +830,7 @@ func TestCloud_VerifyWorkspaceTerraformVersion_workspaceErrors(t *testing.T) {
if _, err := b.client.Workspaces.Update(
context.Background(),
b.organization,
b.workspace,
b.workspaceMapping.name,
tfe.WorkspaceUpdateOptions{
TerraformVersion: tfe.String("1.0.cheetarah"),
},
@ -878,7 +878,7 @@ func TestCloud_VerifyWorkspaceTerraformVersion_ignoreFlagSet(t *testing.T) {
if _, err := b.client.Workspaces.Update(
context.Background(),
b.organization,
b.workspace,
b.workspaceMapping.name,
tfe.WorkspaceUpdateOptions{
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.
if b.workspace != "" {
if b.workspaceMapping.name != "" {
_, err = b.client.Workspaces.Create(ctx, b.organization, tfe.WorkspaceCreateOptions{
Name: tfe.String(b.workspace),
Name: tfe.String(b.workspaceMapping.name),
})
if err != nil {
t.Fatalf("error: %v", err)