mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-25 08:21:07 -06:00
command: Auto-select single workspace if necessary
When initializing a backend, if the currently selected workspace does not exist, the user is prompted to select from the list of workspaces the backend provides. Instead, we should automatically select the only workspace available _if_ that's all that's there. Although with being a nice bit of polish, this enables future improvments with Terraform Cloud in potentially removing the implicit depenency on always using the 'default' workspace when the current configuration is mapped to a single TFC workspace.
This commit is contained in:
parent
cd1d30ea95
commit
60bc7aa05d
@ -196,13 +196,19 @@ func (m *Meta) selectWorkspace(b backend.Backend) error {
|
||||
var list strings.Builder
|
||||
for i, w := range workspaces {
|
||||
if w == workspace {
|
||||
log.Printf("[TRACE] Meta.selectWorkspace: the currently selected workspace is present in the configured backend (%s)", workspace)
|
||||
return nil
|
||||
}
|
||||
fmt.Fprintf(&list, "%d. %s\n", i+1, w)
|
||||
}
|
||||
|
||||
// If the selected workspace doesn't exist, ask the user to select
|
||||
// a workspace from the list of existing workspaces.
|
||||
// If the backend only has a single workspace, select that as the current workspace
|
||||
if len(workspaces) == 1 {
|
||||
log.Printf("[TRACE] Meta.selectWorkspace: automatically selecting the single workspace provided by the backend (%s)", workspaces[0])
|
||||
return m.SetWorkspace(workspaces[0])
|
||||
}
|
||||
|
||||
// Otherwise, ask the user to select a workspace from the list of existing workspaces.
|
||||
v, err := m.UIInput().Input(context.Background(), &terraform.InputOpts{
|
||||
Id: "select-workspace",
|
||||
Query: fmt.Sprintf(
|
||||
@ -220,7 +226,9 @@ func (m *Meta) selectWorkspace(b backend.Backend) error {
|
||||
return fmt.Errorf("Failed to select workspace: input not a valid number")
|
||||
}
|
||||
|
||||
return m.SetWorkspace(workspaces[idx-1])
|
||||
workspace = workspaces[idx-1]
|
||||
log.Printf("[TRACE] Meta.selectWorkspace: setting the current workpace according to user selection (%s)", workspace)
|
||||
return m.SetWorkspace(workspace)
|
||||
}
|
||||
|
||||
// BackendForPlan is similar to Backend, but uses backend settings that were
|
||||
|
@ -789,6 +789,84 @@ func TestMetaBackend_reconfigureChange(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Initializing a backend which supports workspaces and does *not* have
|
||||
// the currently selected workspace should prompt the user with a list of
|
||||
// workspaces to choose from to select a valid one, if more than one workspace
|
||||
// is available.
|
||||
func TestMetaBackend_initSelectedWorkspaceDoesNotExist(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("init-backend-selected-workspace-doesnt-exist-multi"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
// Setup the meta
|
||||
m := testMetaBackend(t, nil)
|
||||
|
||||
defer testInputMap(t, map[string]string{
|
||||
"select-workspace": "2",
|
||||
})()
|
||||
|
||||
// Get the backend
|
||||
_, diags := m.Backend(&BackendOpts{Init: true})
|
||||
if diags.HasErrors() {
|
||||
t.Fatal(diags.Err())
|
||||
}
|
||||
|
||||
expected := "foo"
|
||||
actual, err := m.Workspace()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if actual != expected {
|
||||
t.Fatalf("expected selected workspace to be %q, but was %q", expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
// Initializing a backend which supports workspaces and does *not* have the
|
||||
// currently selected workspace - and which only has a single workspace - should
|
||||
// automatically select that single workspace.
|
||||
func TestMetaBackend_initSelectedWorkspaceDoesNotExistAutoSelect(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
testCopyDir(t, testFixturePath("init-backend-selected-workspace-doesnt-exist-single"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
// Setup the meta
|
||||
m := testMetaBackend(t, nil)
|
||||
|
||||
// this should not ask for input
|
||||
m.input = false
|
||||
|
||||
// Assert test precondition: The current selected workspace is "bar"
|
||||
previousName, err := m.Workspace()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if previousName != "bar" {
|
||||
t.Fatalf("expected test fixture to start with 'bar' as the current selected workspace")
|
||||
}
|
||||
|
||||
// Get the backend
|
||||
_, diags := m.Backend(&BackendOpts{Init: true})
|
||||
if diags.HasErrors() {
|
||||
t.Fatal(diags.Err())
|
||||
}
|
||||
|
||||
expected := "default"
|
||||
actual, err := m.Workspace()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if actual != expected {
|
||||
t.Fatalf("expected selected workspace to be %q, but was %q", expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
// Changing a configured backend, copying state
|
||||
func TestMetaBackend_configuredChangeCopy(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
@ -1267,7 +1345,6 @@ func TestMetaBackend_configuredChangeCopy_multiToNoDefaultWithoutDefault(t *test
|
||||
// Ask input
|
||||
defer testInputMap(t, map[string]string{
|
||||
"backend-migrate-multistate-to-multistate": "yes",
|
||||
"select-workspace": "1",
|
||||
})()
|
||||
|
||||
// Setup the meta
|
||||
|
@ -0,0 +1 @@
|
||||
bar
|
@ -0,0 +1,23 @@
|
||||
{
|
||||
"version": 3,
|
||||
"serial": 2,
|
||||
"lineage": "2f3864a6-1d3e-1999-0f84-36cdb61179d3",
|
||||
"backend": {
|
||||
"type": "local",
|
||||
"config": {
|
||||
"path": null,
|
||||
"workspace_dir": null
|
||||
},
|
||||
"hash": 666019178
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"path": [
|
||||
"root"
|
||||
],
|
||||
"outputs": {},
|
||||
"resources": {},
|
||||
"depends_on": []
|
||||
}
|
||||
]
|
||||
}
|
7
internal/command/testdata/init-backend-selected-workspace-doesnt-exist-multi/main.tf
vendored
Normal file
7
internal/command/testdata/init-backend-selected-workspace-doesnt-exist-multi/main.tf
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
terraform {
|
||||
backend "local" {}
|
||||
}
|
||||
|
||||
output "foo" {
|
||||
value = "bar"
|
||||
}
|
13
internal/command/testdata/init-backend-selected-workspace-doesnt-exist-multi/terraform.tfstate
vendored
Normal file
13
internal/command/testdata/init-backend-selected-workspace-doesnt-exist-multi/terraform.tfstate
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"version": 4,
|
||||
"terraform_version": "1.1.0",
|
||||
"serial": 1,
|
||||
"lineage": "cc4bb587-aa35-87ad-b3b7-7abdb574f2a1",
|
||||
"outputs": {
|
||||
"foo": {
|
||||
"value": "bar",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"resources": []
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
{
|
||||
"version": 4,
|
||||
"terraform_version": "1.1.0",
|
||||
"serial": 1,
|
||||
"lineage": "8ad3c77d-51aa-d90a-4f12-176f538b6e8b",
|
||||
"outputs": {
|
||||
"foo": {
|
||||
"value": "bar",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"resources": []
|
||||
}
|
@ -0,0 +1 @@
|
||||
bar
|
@ -0,0 +1,23 @@
|
||||
{
|
||||
"version": 3,
|
||||
"serial": 2,
|
||||
"lineage": "2f3864a6-1d3e-1999-0f84-36cdb61179d3",
|
||||
"backend": {
|
||||
"type": "local",
|
||||
"config": {
|
||||
"path": null,
|
||||
"workspace_dir": null
|
||||
},
|
||||
"hash": 666019178
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"path": [
|
||||
"root"
|
||||
],
|
||||
"outputs": {},
|
||||
"resources": {},
|
||||
"depends_on": []
|
||||
}
|
||||
]
|
||||
}
|
7
internal/command/testdata/init-backend-selected-workspace-doesnt-exist-single/main.tf
vendored
Normal file
7
internal/command/testdata/init-backend-selected-workspace-doesnt-exist-single/main.tf
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
terraform {
|
||||
backend "local" {}
|
||||
}
|
||||
|
||||
output "foo" {
|
||||
value = "bar"
|
||||
}
|
Loading…
Reference in New Issue
Block a user