Remove prefix from the cloud backend config
Now that we have tags we no longer need prefix.
This commit is contained in:
parent
edbc84420c
commit
83337de654
|
@ -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".`
|
||||
)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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"}},
|
||||
)
|
||||
)
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue