From 83337de6540da9012453669f3fa5400795aa9db7 Mon Sep 17 00:00:00 2001 From: Barrett Clark Date: Mon, 11 Oct 2021 16:26:07 -0500 Subject: [PATCH] Remove prefix from the cloud backend config Now that we have tags we no longer need prefix. --- internal/cloud/backend.go | 73 ++------ internal/cloud/backend_apply_test.go | 18 +- internal/cloud/backend_context.go | 7 +- internal/cloud/backend_plan_test.go | 8 +- internal/cloud/backend_test.go | 246 ++++++--------------------- internal/cloud/errors.go | 4 +- internal/cloud/testing.go | 27 +-- 7 files changed, 81 insertions(+), 302 deletions(-) diff --git a/internal/cloud/backend.go b/internal/cloud/backend.go index 2e611745e..2bf5d3c4d 100644 --- a/internal/cloud/backend.go +++ b/internal/cloud/backend.go @@ -128,11 +128,6 @@ func (b *Cloud) ConfigSchema() *configschema.Block { Optional: true, Description: schemaDescriptionName, }, - "prefix": { - Type: cty.String, - Optional: true, - Description: schemaDescriptionPrefix, - }, "tags": { Type: cty.Set(cty.String), Optional: true, @@ -162,9 +157,6 @@ func (b *Cloud) PrepareConfig(obj cty.Value) (cty.Value, tfdiags.Diagnostics) { if val := workspaces.GetAttr("name"); !val.IsNull() { WorkspaceMapping.Name = val.AsString() } - if val := workspaces.GetAttr("prefix"); !val.IsNull() { - WorkspaceMapping.Prefix = val.AsString() - } if val := workspaces.GetAttr("tags"); !val.IsNull() { err := gocty.FromCtyValue(val, &WorkspaceMapping.Tags) if err != nil { @@ -177,7 +169,7 @@ func (b *Cloud) PrepareConfig(obj cty.Value) (cty.Value, tfdiags.Diagnostics) { // Make sure have a workspace mapping strategy present case WorkspaceNoneStrategy: diags = diags.Append(invalidWorkspaceConfigMissingValues) - // Make sure that only one of workspace name or a prefix is configured. + // Make sure that a workspace name is configured. case WorkspaceInvalidStrategy: diags = diags.Append(invalidWorkspaceConfigMisconfiguration) } @@ -339,16 +331,13 @@ func (b *Cloud) setConfigurationFields(obj cty.Value) tfdiags.Diagnostics { } // Get the workspaces configuration block and retrieve the - // default workspace name and prefix. + // default workspace name. if workspaces := obj.GetAttr("workspaces"); !workspaces.IsNull() { // PrepareConfig checks that you cannot set both of these. if val := workspaces.GetAttr("name"); !val.IsNull() { b.WorkspaceMapping.Name = val.AsString() } - if val := workspaces.GetAttr("prefix"); !val.IsNull() { - b.WorkspaceMapping.Prefix = val.AsString() - } if val := workspaces.GetAttr("tags"); !val.IsNull() { var tags []string err := gocty.FromCtyValue(val, &tags) @@ -447,10 +436,7 @@ func (b *Cloud) Workspaces() ([]string, error) { // Otherwise, multiple workspaces are being mapped. Query Terraform Cloud for all the remote // workspaces by the provided mapping strategy. options := tfe.WorkspaceListOptions{} - switch b.WorkspaceMapping.Strategy() { - case WorkspacePrefixStrategy: - options.Search = tfe.String(b.WorkspaceMapping.Prefix) - case WorkspaceTagsStrategy: + if b.WorkspaceMapping.Strategy() == WorkspaceTagsStrategy { taglist := strings.Join(b.WorkspaceMapping.Tags, ",") options.Tags = &taglist } @@ -462,18 +448,7 @@ func (b *Cloud) Workspaces() ([]string, error) { } for _, w := range wl.Items { - switch b.WorkspaceMapping.Strategy() { - case WorkspacePrefixStrategy: - if strings.HasPrefix(w.Name, b.WorkspaceMapping.Prefix) { - names = append(names, strings.TrimPrefix(w.Name, b.WorkspaceMapping.Prefix)) - continue - } - default: - // Pass-through. The "prefix" strategy is naive and does - // client-side filtering, but for tags and any other future - // strategy this filtering should be left to the API. - names = append(names, w.Name) - } + names = append(names, w.Name) } // Exit the loop when we've seen all pages. @@ -502,11 +477,6 @@ func (b *Cloud) DeleteWorkspace(name string) error { } // Configure the remote workspace name. - switch { - case b.WorkspaceMapping.Strategy() == WorkspacePrefixStrategy && !strings.HasPrefix(name, b.WorkspaceMapping.Prefix): - name = b.WorkspaceMapping.Prefix + name - } - client := &remoteClient{ client: b.client, organization: b.organization, @@ -528,11 +498,6 @@ func (b *Cloud) StateMgr(name string) (statemgr.Full, error) { return nil, backend.ErrWorkspacesNotSupported } - // If the prefix strategy is used, translate the local name to the TFC workspace name. - if b.WorkspaceMapping.Strategy() == WorkspacePrefixStrategy { - name = b.WorkspaceMapping.Prefix + name - } - workspace, err := b.client.Workspaces.Read(context.Background(), b.organization, name) if err != nil && err != tfe.ErrResourceNotFound { return nil, fmt.Errorf("Failed to retrieve workspace %s: %v", name, err) @@ -588,11 +553,6 @@ func (b *Cloud) StateMgr(name string) (statemgr.Full, error) { func (b *Cloud) Operation(ctx context.Context, op *backend.Operation) (*backend.RunningOperation, error) { name := op.Workspace - // If the prefix strategy is used, translate the local name to the TFC workspace name. - if b.WorkspaceMapping.Strategy() == WorkspacePrefixStrategy { - name = b.WorkspaceMapping.Prefix + op.Workspace - } - // Retrieve the workspace for this operation. w, err := b.client.Workspaces.Read(ctx, b.organization, name) if err != nil { @@ -908,9 +868,8 @@ func (b *Cloud) cliColorize() *colorstring.Colorize { } type WorkspaceMapping struct { - Name string - Prefix string - Tags []string + Name string + Tags []string } type workspaceStrategy string @@ -918,20 +877,17 @@ type workspaceStrategy string const ( WorkspaceTagsStrategy workspaceStrategy = "tags" WorkspaceNameStrategy workspaceStrategy = "name" - WorkspacePrefixStrategy workspaceStrategy = "prefix" WorkspaceNoneStrategy workspaceStrategy = "none" WorkspaceInvalidStrategy workspaceStrategy = "invalid" ) func (wm WorkspaceMapping) Strategy() workspaceStrategy { switch { - case len(wm.Tags) > 0 && wm.Name == "" && wm.Prefix == "": + case len(wm.Tags) > 0 && wm.Name == "": return WorkspaceTagsStrategy - case len(wm.Tags) == 0 && wm.Name != "" && wm.Prefix == "": + case len(wm.Tags) == 0 && wm.Name != "": return WorkspaceNameStrategy - case len(wm.Tags) == 0 && wm.Name == "" && wm.Prefix != "": - return WorkspacePrefixStrategy - case len(wm.Tags) == 0 && wm.Name == "" && wm.Prefix == "": + case len(wm.Tags) == 0 && wm.Name == "": return WorkspaceNoneStrategy default: // Any other combination is invalid as each strategy is mutually exclusive @@ -999,9 +955,7 @@ configuration to workspaces within a Terraform Cloud organization. Three strateg [bold]tags[reset] - %s -[bold]name[reset] - %s - -[bold]prefix[reset] - %s`, schemaDescriptionTags, schemaDescriptionName, schemaDescriptionPrefix) +[bold]name[reset] - %s`, schemaDescriptionTags, schemaDescriptionName) schemaDescriptionHostname = `The Terraform Enterprise hostname to connect to. This optional argument defaults to app.terraform.io for use with Terraform Cloud.` @@ -1014,11 +968,8 @@ configuration file or configured credential helper.` schemaDescriptionTags = `A set of tags used to select remote Terraform Cloud workspaces to be used for this single configuration. New workspaces will automatically be tagged with these tag values. Generally, this -is the primary and recommended strategy to use. This option conflicts with "prefix" and "name".` +is the primary and recommended strategy to use. This option conflicts with "name".` schemaDescriptionName = `The name of a single Terraform Cloud workspace to be used with this configuration When configured -only the specified workspace can be used. This option conflicts with "tags" and "prefix".` - - schemaDescriptionPrefix = `DEPRECATED. A name prefix used to select remote Terraform Cloud to be used for this single configuration. New -workspaces will automatically be prefixed with this prefix. This option conflicts with "tags" and "name".` +only the specified workspace can be used. This option conflicts with "tags".` ) diff --git a/internal/cloud/backend_apply_test.go b/internal/cloud/backend_apply_test.go index 0151f39bc..fc5e99337 100644 --- a/internal/cloud/backend_apply_test.go +++ b/internal/cloud/backend_apply_test.go @@ -143,7 +143,7 @@ func TestCloud_applyCanceled(t *testing.T) { } func TestCloud_applyWithoutPermissions(t *testing.T) { - b, bCleanup := testBackendWithPrefix(t) + b, bCleanup := testBackendWithTags(t) defer bCleanup() // Create a named workspace without permissions. @@ -151,7 +151,7 @@ func TestCloud_applyWithoutPermissions(t *testing.T) { context.Background(), b.organization, tfe.WorkspaceCreateOptions{ - Name: tfe.String(b.WorkspaceMapping.Prefix + "prod"), + Name: tfe.String("prod"), }, ) if err != nil { @@ -183,7 +183,7 @@ func TestCloud_applyWithoutPermissions(t *testing.T) { } func TestCloud_applyWithVCS(t *testing.T) { - b, bCleanup := testBackendWithPrefix(t) + b, bCleanup := testBackendWithTags(t) defer bCleanup() // Create a named workspace with a VCS. @@ -191,7 +191,7 @@ func TestCloud_applyWithVCS(t *testing.T) { context.Background(), b.organization, tfe.WorkspaceCreateOptions{ - Name: tfe.String(b.WorkspaceMapping.Prefix + "prod"), + Name: tfe.String("prod"), VCSRepo: &tfe.VCSRepoOptions{}, }, ) @@ -774,7 +774,7 @@ func TestCloud_applyDiscardedExternally(t *testing.T) { } func TestCloud_applyWithAutoApprove(t *testing.T) { - b, bCleanup := testBackendWithPrefix(t) + b, bCleanup := testBackendWithTags(t) defer bCleanup() ctrl := gomock.NewController(t) @@ -790,7 +790,7 @@ func TestCloud_applyWithAutoApprove(t *testing.T) { context.Background(), b.organization, tfe.WorkspaceCreateOptions{ - Name: tfe.String(b.WorkspaceMapping.Prefix + "prod"), + Name: tfe.String("prod"), }, ) if err != nil { @@ -896,7 +896,7 @@ func TestCloud_applyForceLocal(t *testing.T) { } func TestCloud_applyWorkspaceWithoutOperations(t *testing.T) { - b, bCleanup := testBackendWithPrefix(t) + b, bCleanup := testBackendWithTags(t) defer bCleanup() ctx := context.Background() @@ -906,7 +906,7 @@ func TestCloud_applyWorkspaceWithoutOperations(t *testing.T) { ctx, b.organization, tfe.WorkspaceCreateOptions{ - Name: tfe.String(b.WorkspaceMapping.Prefix + "no-operations"), + Name: tfe.String("no-operations"), }, ) if err != nil { @@ -1360,7 +1360,7 @@ func TestCloud_applyPolicySoftFailAutoApprove(t *testing.T) { context.Background(), b.organization, tfe.WorkspaceCreateOptions{ - Name: tfe.String(b.WorkspaceMapping.Prefix + "prod"), + Name: tfe.String("prod"), }, ) if err != nil { diff --git a/internal/cloud/backend_context.go b/internal/cloud/backend_context.go index 24ed97854..27afadd2f 100644 --- a/internal/cloud/backend_context.go +++ b/internal/cloud/backend_context.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "log" - "strings" tfe "github.com/hashicorp/go-tfe" "github.com/hashicorp/hcl/v2" @@ -140,12 +139,8 @@ func (b *Cloud) LocalRun(op *backend.Operation) (*backend.LocalRun, statemgr.Ful func (b *Cloud) getRemoteWorkspaceName(localWorkspaceName string) string { switch { case localWorkspaceName == backend.DefaultStateName: - // 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_. + // The default workspace name is a special case return b.WorkspaceMapping.Name - case b.WorkspaceMapping.Prefix != "" && !strings.HasPrefix(localWorkspaceName, b.WorkspaceMapping.Prefix): - return b.WorkspaceMapping.Prefix + localWorkspaceName default: return localWorkspaceName } diff --git a/internal/cloud/backend_plan_test.go b/internal/cloud/backend_plan_test.go index 6c08c3762..ba2508091 100644 --- a/internal/cloud/backend_plan_test.go +++ b/internal/cloud/backend_plan_test.go @@ -159,7 +159,7 @@ func TestCloud_planLongLine(t *testing.T) { } func TestCloud_planWithoutPermissions(t *testing.T) { - b, bCleanup := testBackendWithPrefix(t) + b, bCleanup := testBackendWithTags(t) defer bCleanup() // Create a named workspace without permissions. @@ -167,7 +167,7 @@ func TestCloud_planWithoutPermissions(t *testing.T) { context.Background(), b.organization, tfe.WorkspaceCreateOptions{ - Name: tfe.String(b.WorkspaceMapping.Prefix + "prod"), + Name: tfe.String("prod"), }, ) if err != nil { @@ -639,7 +639,7 @@ func TestCloud_planWithoutOperationsEntitlement(t *testing.T) { } func TestCloud_planWorkspaceWithoutOperations(t *testing.T) { - b, bCleanup := testBackendWithPrefix(t) + b, bCleanup := testBackendWithTags(t) defer bCleanup() ctx := context.Background() @@ -649,7 +649,7 @@ func TestCloud_planWorkspaceWithoutOperations(t *testing.T) { ctx, b.organization, tfe.WorkspaceCreateOptions{ - Name: tfe.String(b.WorkspaceMapping.Prefix + "no-operations"), + Name: tfe.String("no-operations"), }, ) if err != nil { diff --git a/internal/cloud/backend_test.go b/internal/cloud/backend_test.go index 01072898c..ed9a675ee 100644 --- a/internal/cloud/backend_test.go +++ b/internal/cloud/backend_test.go @@ -5,7 +5,6 @@ import ( "fmt" "net/http" "os" - "reflect" "strings" "testing" @@ -50,13 +49,6 @@ func TestCloud_backendWithName(t *testing.T) { } } -func TestCloud_backendWithPrefix(t *testing.T) { - b, bCleanup := testBackendWithPrefix(t) - defer bCleanup() - - backend.TestBackendStates(t, b) -} - func TestCloud_backendWithTags(t *testing.T) { b, bCleanup := testBackendWithTags(t) defer bCleanup() @@ -90,9 +82,8 @@ func TestCloud_PrepareConfig(t *testing.T) { config: cty.ObjectVal(map[string]cty.Value{ "organization": cty.NullVal(cty.String), "workspaces": cty.ObjectVal(map[string]cty.Value{ - "name": cty.StringVal("prod"), - "prefix": cty.NullVal(cty.String), - "tags": cty.NullVal(cty.Set(cty.String)), + "name": cty.StringVal("prod"), + "tags": cty.NullVal(cty.Set(cty.String)), }), }), expectedErr: `Invalid organization value: The "organization" attribute value must not be empty.`, @@ -102,36 +93,33 @@ func TestCloud_PrepareConfig(t *testing.T) { "organization": cty.StringVal("org"), "workspaces": cty.NullVal(cty.String), }), - expectedErr: `Invalid workspaces configuration: Missing workspace mapping strategy. Either workspace "tags", "name", or "prefix" is required.`, + expectedErr: `Invalid workspaces configuration: Missing workspace mapping strategy. Either workspace "tags" or "name" is required.`, }, - "workspace: empty tags, name, and prefix": { + "workspace: empty tags, name": { config: cty.ObjectVal(map[string]cty.Value{ "organization": cty.StringVal("org"), "workspaces": cty.ObjectVal(map[string]cty.Value{ - "name": cty.NullVal(cty.String), - "prefix": cty.NullVal(cty.String), - "tags": cty.NullVal(cty.Set(cty.String)), + "name": cty.NullVal(cty.String), + "tags": cty.NullVal(cty.Set(cty.String)), }), }), - expectedErr: `Invalid workspaces configuration: Missing workspace mapping strategy. Either workspace "tags", "name", or "prefix" is required.`, + expectedErr: `Invalid workspaces configuration: Missing workspace mapping strategy. Either workspace "tags" or "name" is required.`, }, - "workspace: name and prefix present": { + "workspace: name present": { config: cty.ObjectVal(map[string]cty.Value{ "organization": cty.StringVal("org"), "workspaces": cty.ObjectVal(map[string]cty.Value{ - "name": cty.StringVal("prod"), - "prefix": cty.StringVal("app-"), - "tags": cty.NullVal(cty.Set(cty.String)), + "name": cty.StringVal("prod"), + "tags": cty.NullVal(cty.Set(cty.String)), }), }), - expectedErr: `Invalid workspaces configuration: Only one of workspace "tags", "name", or "prefix" is allowed.`, + expectedErr: `Invalid workspaces configuration: Only one of workspace "tags" or "name" is allowed.`, }, "workspace: name and tags present": { config: cty.ObjectVal(map[string]cty.Value{ "organization": cty.StringVal("org"), "workspaces": cty.ObjectVal(map[string]cty.Value{ - "name": cty.StringVal("prod"), - "prefix": cty.NullVal(cty.String), + "name": cty.StringVal("prod"), "tags": cty.SetVal( []cty.Value{ cty.StringVal("billing"), @@ -139,7 +127,7 @@ func TestCloud_PrepareConfig(t *testing.T) { ), }), }), - expectedErr: `Invalid workspaces configuration: Only one of workspace "tags", "name", or "prefix" is allowed.`, + expectedErr: `Invalid workspaces configuration: Only one of workspace "tags" or "name" is allowed.`, }, } @@ -170,9 +158,8 @@ func TestCloud_config(t *testing.T) { "organization": cty.StringVal("nonexisting"), "token": cty.NullVal(cty.String), "workspaces": cty.ObjectVal(map[string]cty.Value{ - "name": cty.StringVal("prod"), - "prefix": cty.NullVal(cty.String), - "tags": cty.NullVal(cty.Set(cty.String)), + "name": cty.StringVal("prod"), + "tags": cty.NullVal(cty.Set(cty.String)), }), }), confErr: "organization \"nonexisting\" at host app.terraform.io not found", @@ -183,9 +170,8 @@ func TestCloud_config(t *testing.T) { "organization": cty.StringVal("hashicorp"), "token": cty.NullVal(cty.String), "workspaces": cty.ObjectVal(map[string]cty.Value{ - "name": cty.StringVal("prod"), - "prefix": cty.NullVal(cty.String), - "tags": cty.NullVal(cty.Set(cty.String)), + "name": cty.StringVal("prod"), + "tags": cty.NullVal(cty.Set(cty.String)), }), }), confErr: "Failed to request discovery document", @@ -197,9 +183,8 @@ func TestCloud_config(t *testing.T) { "organization": cty.StringVal("hashicorp"), "token": cty.NullVal(cty.String), "workspaces": cty.ObjectVal(map[string]cty.Value{ - "name": cty.StringVal("prod"), - "prefix": cty.NullVal(cty.String), - "tags": cty.NullVal(cty.Set(cty.String)), + "name": cty.StringVal("prod"), + "tags": cty.NullVal(cty.Set(cty.String)), }), }), confErr: "terraform login localhost", @@ -210,8 +195,7 @@ func TestCloud_config(t *testing.T) { "organization": cty.StringVal("hashicorp"), "token": cty.NullVal(cty.String), "workspaces": cty.ObjectVal(map[string]cty.Value{ - "name": cty.NullVal(cty.String), - "prefix": cty.NullVal(cty.String), + "name": cty.NullVal(cty.String), "tags": cty.SetVal( []cty.Value{ cty.StringVal("billing"), @@ -226,58 +210,30 @@ func TestCloud_config(t *testing.T) { "organization": cty.StringVal("hashicorp"), "token": cty.NullVal(cty.String), "workspaces": cty.ObjectVal(map[string]cty.Value{ - "name": cty.StringVal("prod"), - "prefix": cty.NullVal(cty.String), - "tags": cty.NullVal(cty.Set(cty.String)), + "name": cty.StringVal("prod"), + "tags": cty.NullVal(cty.Set(cty.String)), }), }), }, - "with_a_prefix": { + "without_a_name_tags": { config: cty.ObjectVal(map[string]cty.Value{ "hostname": cty.NullVal(cty.String), "organization": cty.StringVal("hashicorp"), "token": cty.NullVal(cty.String), "workspaces": cty.ObjectVal(map[string]cty.Value{ - "name": cty.NullVal(cty.String), - "prefix": cty.StringVal("my-app-"), - "tags": cty.NullVal(cty.Set(cty.String)), - }), - }), - }, - "without_a_name_prefix_or_tags": { - config: cty.ObjectVal(map[string]cty.Value{ - "hostname": cty.NullVal(cty.String), - "organization": cty.StringVal("hashicorp"), - "token": cty.NullVal(cty.String), - "workspaces": cty.ObjectVal(map[string]cty.Value{ - "name": cty.NullVal(cty.String), - "prefix": cty.NullVal(cty.String), - "tags": cty.NullVal(cty.Set(cty.String)), + "name": cty.NullVal(cty.String), + "tags": cty.NullVal(cty.Set(cty.String)), }), }), valErr: `Missing workspace mapping strategy.`, }, - "with_both_a_name_and_a_prefix": { - config: cty.ObjectVal(map[string]cty.Value{ - "hostname": cty.NullVal(cty.String), - "organization": cty.StringVal("hashicorp"), - "token": cty.NullVal(cty.String), - "workspaces": cty.ObjectVal(map[string]cty.Value{ - "name": cty.StringVal("prod"), - "prefix": cty.StringVal("my-app-"), - "tags": cty.NullVal(cty.Set(cty.String)), - }), - }), - valErr: `Only one of workspace "tags", "name", or "prefix" is allowed.`, - }, "with_both_a_name_and_tags": { config: cty.ObjectVal(map[string]cty.Value{ "hostname": cty.NullVal(cty.String), "organization": cty.StringVal("hashicorp"), "token": cty.NullVal(cty.String), "workspaces": cty.ObjectVal(map[string]cty.Value{ - "name": cty.StringVal("prod"), - "prefix": cty.NullVal(cty.String), + "name": cty.StringVal("prod"), "tags": cty.SetVal( []cty.Value{ cty.StringVal("billing"), @@ -285,7 +241,7 @@ func TestCloud_config(t *testing.T) { ), }), }), - valErr: `Only one of workspace "tags", "name", or "prefix" is allowed.`, + valErr: `Only one of workspace "tags" or "name" is allowed.`, }, "null config": { config: cty.NullVal(cty.EmptyObject), @@ -318,8 +274,7 @@ func TestCloud_configVerifyMinimumTFEVersion(t *testing.T) { "organization": cty.StringVal("hashicorp"), "token": cty.NullVal(cty.String), "workspaces": cty.ObjectVal(map[string]cty.Value{ - "name": cty.NullVal(cty.String), - "prefix": cty.NullVal(cty.String), + "name": cty.NullVal(cty.String), "tags": cty.SetVal( []cty.Value{ cty.StringVal("billing"), @@ -353,25 +308,23 @@ func TestCloud_setConfigurationFields(t *testing.T) { originalForceBackendEnv := os.Getenv("TF_FORCE_LOCAL_BACKEND") cases := map[string]struct { - obj cty.Value - expectedHostname string - expectedOrganziation string - expectedWorkspacePrefix string - expectedWorkspaceName string - expectedWorkspaceTags []string - expectedForceLocal bool - setEnv func() - resetEnv func() - expectedErr string + obj cty.Value + expectedHostname string + expectedOrganziation string + expectedWorkspaceName string + expectedWorkspaceTags []string + expectedForceLocal bool + setEnv func() + resetEnv func() + expectedErr string }{ "with hostname set": { obj: cty.ObjectVal(map[string]cty.Value{ "organization": cty.StringVal("hashicorp"), "hostname": cty.StringVal("hashicorp.com"), "workspaces": cty.ObjectVal(map[string]cty.Value{ - "name": cty.StringVal("prod"), - "prefix": cty.NullVal(cty.String), - "tags": cty.NullVal(cty.Set(cty.String)), + "name": cty.StringVal("prod"), + "tags": cty.NullVal(cty.Set(cty.String)), }), }), expectedHostname: "hashicorp.com", @@ -382,9 +335,8 @@ func TestCloud_setConfigurationFields(t *testing.T) { "organization": cty.StringVal("hashicorp"), "hostname": cty.NullVal(cty.String), "workspaces": cty.ObjectVal(map[string]cty.Value{ - "name": cty.StringVal("prod"), - "prefix": cty.NullVal(cty.String), - "tags": cty.NullVal(cty.Set(cty.String)), + "name": cty.StringVal("prod"), + "tags": cty.NullVal(cty.Set(cty.String)), }), }), expectedHostname: defaultHostname, @@ -395,36 +347,20 @@ func TestCloud_setConfigurationFields(t *testing.T) { "organization": cty.StringVal("hashicorp"), "hostname": cty.StringVal("hashicorp.com"), "workspaces": cty.ObjectVal(map[string]cty.Value{ - "name": cty.StringVal("prod"), - "prefix": cty.NullVal(cty.String), - "tags": cty.NullVal(cty.Set(cty.String)), + "name": cty.StringVal("prod"), + "tags": cty.NullVal(cty.Set(cty.String)), }), }), expectedHostname: "hashicorp.com", expectedOrganziation: "hashicorp", expectedWorkspaceName: "prod", }, - "with workspace prefix set": { - obj: cty.ObjectVal(map[string]cty.Value{ - "organization": cty.StringVal("hashicorp"), - "hostname": cty.StringVal("hashicorp.com"), - "workspaces": cty.ObjectVal(map[string]cty.Value{ - "name": cty.NullVal(cty.String), - "prefix": cty.StringVal("prod"), - "tags": cty.NullVal(cty.Set(cty.String)), - }), - }), - expectedHostname: "hashicorp.com", - expectedOrganziation: "hashicorp", - expectedWorkspacePrefix: "prod", - }, "with workspace tags set": { obj: cty.ObjectVal(map[string]cty.Value{ "organization": cty.StringVal("hashicorp"), "hostname": cty.StringVal("hashicorp.com"), "workspaces": cty.ObjectVal(map[string]cty.Value{ - "name": cty.NullVal(cty.String), - "prefix": cty.NullVal(cty.String), + "name": cty.NullVal(cty.String), "tags": cty.SetVal( []cty.Value{ cty.StringVal("billing"), @@ -441,14 +377,12 @@ func TestCloud_setConfigurationFields(t *testing.T) { "organization": cty.StringVal("hashicorp"), "hostname": cty.StringVal("hashicorp.com"), "workspaces": cty.ObjectVal(map[string]cty.Value{ - "name": cty.NullVal(cty.String), - "prefix": cty.StringVal("prod"), - "tags": cty.NullVal(cty.Set(cty.String)), + "name": cty.NullVal(cty.String), + "tags": cty.NullVal(cty.Set(cty.String)), }), }), - expectedHostname: "hashicorp.com", - expectedOrganziation: "hashicorp", - expectedWorkspacePrefix: "prod", + expectedHostname: "hashicorp.com", + expectedOrganziation: "hashicorp", setEnv: func() { os.Setenv("TF_FORCE_LOCAL_BACKEND", "1") }, @@ -482,9 +416,6 @@ func TestCloud_setConfigurationFields(t *testing.T) { if tc.expectedOrganziation != "" && b.organization != tc.expectedOrganziation { t.Fatalf("%s: expected organization (%s) to match configured organization (%s)", name, b.organization, tc.expectedOrganziation) } - if tc.expectedWorkspacePrefix != "" && b.WorkspaceMapping.Prefix != tc.expectedWorkspacePrefix { - t.Fatalf("%s: expected workspace prefix mapping (%s) to match configured workspace prefix (%s)", name, b.WorkspaceMapping.Prefix, tc.expectedWorkspacePrefix) - } if tc.expectedWorkspaceName != "" && b.WorkspaceMapping.Name != tc.expectedWorkspaceName { t.Fatalf("%s: expected workspace name mapping (%s) to match configured workspace name (%s)", name, b.WorkspaceMapping.Name, tc.expectedWorkspaceName) } @@ -557,87 +488,6 @@ func TestCloud_addAndRemoveWorkspacesDefault(t *testing.T) { } } -func TestCloud_addAndRemoveWorkspacesWithPrefix(t *testing.T) { - b, bCleanup := testBackendWithPrefix(t) - defer bCleanup() - - states, err := b.Workspaces() - if err != nil { - t.Fatal(err) - } - - expectedWorkspaces := []string(nil) - if !reflect.DeepEqual(states, expectedWorkspaces) { - t.Fatalf("expected states %#+v, got %#+v", expectedWorkspaces, states) - } - - if _, err := b.StateMgr(backend.DefaultStateName); err != backend.ErrDefaultWorkspaceNotSupported { - t.Fatalf("expected error %v, got %v", backend.ErrDefaultWorkspaceNotSupported, err) - } - - expectedA := "test_A" - if _, err := b.StateMgr(expectedA); err != nil { - t.Fatal(err) - } - - states, err = b.Workspaces() - if err != nil { - t.Fatal(err) - } - - expectedWorkspaces = append(expectedWorkspaces, expectedA) - if !reflect.DeepEqual(states, expectedWorkspaces) { - t.Fatalf("expected %#+v, got %#+v", expectedWorkspaces, states) - } - - expectedB := "test_B" - if _, err := b.StateMgr(expectedB); err != nil { - t.Fatal(err) - } - - states, err = b.Workspaces() - if err != nil { - t.Fatal(err) - } - - expectedWorkspaces = append(expectedWorkspaces, expectedB) - if !reflect.DeepEqual(states, expectedWorkspaces) { - t.Fatalf("expected %#+v, got %#+v", expectedWorkspaces, states) - } - - if err := b.DeleteWorkspace(backend.DefaultStateName); err != backend.ErrDefaultWorkspaceNotSupported { - t.Fatalf("expected error %v, got %v", backend.ErrDefaultWorkspaceNotSupported, err) - } - - if err := b.DeleteWorkspace(expectedA); err != nil { - t.Fatal(err) - } - - states, err = b.Workspaces() - if err != nil { - t.Fatal(err) - } - - expectedWorkspaces = []string{expectedB} - if !reflect.DeepEqual(states, expectedWorkspaces) { - t.Fatalf("expected %#+v got %#+v", expectedWorkspaces, states) - } - - if err := b.DeleteWorkspace(expectedB); err != nil { - t.Fatal(err) - } - - states, err = b.Workspaces() - if err != nil { - t.Fatal(err) - } - - expectedWorkspaces = []string(nil) - if !reflect.DeepEqual(states, expectedWorkspaces) { - t.Fatalf("expected %#+v, got %#+v", expectedWorkspaces, states) - } -} - func TestCloud_StateMgr_versionCheck(t *testing.T) { b, bCleanup := testBackendWithName(t) defer bCleanup() diff --git a/internal/cloud/errors.go b/internal/cloud/errors.go index 81dfe7bb7..2c5910030 100644 --- a/internal/cloud/errors.go +++ b/internal/cloud/errors.go @@ -18,14 +18,14 @@ var ( invalidWorkspaceConfigMissingValues = tfdiags.AttributeValue( tfdiags.Error, "Invalid workspaces configuration", - fmt.Sprintf("Missing workspace mapping strategy. Either workspace \"tags\", \"name\", or \"prefix\" is required.\n\n%s", workspaceConfigurationHelp), + fmt.Sprintf("Missing workspace mapping strategy. Either workspace \"tags\" or \"name\" is required.\n\n%s", workspaceConfigurationHelp), cty.Path{cty.GetAttrStep{Name: "workspaces"}}, ) invalidWorkspaceConfigMisconfiguration = tfdiags.AttributeValue( tfdiags.Error, "Invalid workspaces configuration", - fmt.Sprintf("Only one of workspace \"tags\", \"name\", or \"prefix\" is allowed.\n\n%s", workspaceConfigurationHelp), + fmt.Sprintf("Only one of workspace \"tags\" or \"name\" is allowed.\n\n%s", workspaceConfigurationHelp), cty.Path{cty.GetAttrStep{Name: "workspaces"}}, ) ) diff --git a/internal/cloud/testing.go b/internal/cloud/testing.go index 75e53c5bc..e7be4748c 100644 --- a/internal/cloud/testing.go +++ b/internal/cloud/testing.go @@ -71,23 +71,8 @@ func testBackendWithName(t *testing.T) (*Cloud, func()) { "organization": cty.StringVal("hashicorp"), "token": cty.NullVal(cty.String), "workspaces": cty.ObjectVal(map[string]cty.Value{ - "name": cty.StringVal(testBackendSingleWorkspaceName), - "prefix": cty.NullVal(cty.String), - "tags": cty.NullVal(cty.Set(cty.String)), - }), - }) - return testBackend(t, obj) -} - -func testBackendWithPrefix(t *testing.T) (*Cloud, func()) { - obj := cty.ObjectVal(map[string]cty.Value{ - "hostname": cty.NullVal(cty.String), - "organization": cty.StringVal("hashicorp"), - "token": cty.NullVal(cty.String), - "workspaces": cty.ObjectVal(map[string]cty.Value{ - "name": cty.NullVal(cty.String), - "prefix": cty.StringVal("my-app-"), - "tags": cty.NullVal(cty.Set(cty.String)), + "name": cty.StringVal(testBackendSingleWorkspaceName), + "tags": cty.NullVal(cty.Set(cty.String)), }), }) return testBackend(t, obj) @@ -99,8 +84,7 @@ func testBackendWithTags(t *testing.T) (*Cloud, func()) { "organization": cty.StringVal("hashicorp"), "token": cty.NullVal(cty.String), "workspaces": cty.ObjectVal(map[string]cty.Value{ - "name": cty.NullVal(cty.String), - "prefix": cty.NullVal(cty.String), + "name": cty.NullVal(cty.String), "tags": cty.SetVal( []cty.Value{ cty.StringVal("billing"), @@ -117,9 +101,8 @@ func testBackendNoOperations(t *testing.T) (*Cloud, func()) { "organization": cty.StringVal("no-operations"), "token": cty.NullVal(cty.String), "workspaces": cty.ObjectVal(map[string]cty.Value{ - "name": cty.StringVal(testBackendSingleWorkspaceName), - "prefix": cty.NullVal(cty.String), - "tags": cty.NullVal(cty.Set(cty.String)), + "name": cty.StringVal(testBackendSingleWorkspaceName), + "tags": cty.NullVal(cty.Set(cty.String)), }), }) return testBackend(t, obj)