command: Always validate workspace name
The workspace name can be overridden by setting a TF_WORKSPACE environment variable. If this is done, we should still validate the resulting workspace name; otherwise, we could end up with an invalid and unselectable workspace. This change updates the Meta.Workspace function to return an error, and handles that error wherever necessary.
This commit is contained in:
parent
31f858e1bb
commit
b239570abb
|
@ -264,7 +264,12 @@ func (c *InitCommand) Run(args []string) int {
|
||||||
// on a previous run) we'll use the current state as a potential source
|
// on a previous run) we'll use the current state as a potential source
|
||||||
// of provider dependencies.
|
// of provider dependencies.
|
||||||
if back != nil {
|
if back != nil {
|
||||||
sMgr, err := back.StateMgr(c.Workspace())
|
workspace, err := c.Workspace()
|
||||||
|
if err != nil {
|
||||||
|
c.Ui.Error(fmt.Sprintf("Error selecting workspace: %s", err))
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
sMgr, err := back.StateMgr(workspace)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Ui.Error(fmt.Sprintf("Error loading state: %s", err))
|
c.Ui.Error(fmt.Sprintf("Error loading state: %s", err))
|
||||||
return 1
|
return 1
|
||||||
|
|
|
@ -341,7 +341,12 @@ const (
|
||||||
|
|
||||||
// contextOpts returns the options to use to initialize a Terraform
|
// contextOpts returns the options to use to initialize a Terraform
|
||||||
// context with the settings from this Meta.
|
// context with the settings from this Meta.
|
||||||
func (m *Meta) contextOpts() *terraform.ContextOpts {
|
func (m *Meta) contextOpts() (*terraform.ContextOpts, error) {
|
||||||
|
workspace, err := m.Workspace()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
var opts terraform.ContextOpts
|
var opts terraform.ContextOpts
|
||||||
opts.Hooks = []terraform.Hook{m.uiHook()}
|
opts.Hooks = []terraform.Hook{m.uiHook()}
|
||||||
opts.Hooks = append(opts.Hooks, m.ExtraHooks...)
|
opts.Hooks = append(opts.Hooks, m.ExtraHooks...)
|
||||||
|
@ -379,10 +384,10 @@ func (m *Meta) contextOpts() *terraform.ContextOpts {
|
||||||
}
|
}
|
||||||
|
|
||||||
opts.Meta = &terraform.ContextMeta{
|
opts.Meta = &terraform.ContextMeta{
|
||||||
Env: m.Workspace(),
|
Env: workspace,
|
||||||
}
|
}
|
||||||
|
|
||||||
return &opts
|
return &opts, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// defaultFlagSet creates a default flag set for commands.
|
// defaultFlagSet creates a default flag set for commands.
|
||||||
|
@ -599,11 +604,16 @@ func (m *Meta) outputShadowError(err error, output bool) bool {
|
||||||
// and `terraform workspace delete`.
|
// and `terraform workspace delete`.
|
||||||
const WorkspaceNameEnvVar = "TF_WORKSPACE"
|
const WorkspaceNameEnvVar = "TF_WORKSPACE"
|
||||||
|
|
||||||
|
var invalidWorkspaceNameEnvVar = fmt.Errorf("Invalid workspace name set using %s", WorkspaceNameEnvVar)
|
||||||
|
|
||||||
// Workspace returns the name of the currently configured workspace, corresponding
|
// Workspace returns the name of the currently configured workspace, corresponding
|
||||||
// to the desired named state.
|
// to the desired named state.
|
||||||
func (m *Meta) Workspace() string {
|
func (m *Meta) Workspace() (string, error) {
|
||||||
current, _ := m.WorkspaceOverridden()
|
current, overridden := m.WorkspaceOverridden()
|
||||||
return current
|
if overridden && !validWorkspaceName(current) {
|
||||||
|
return "", invalidWorkspaceNameEnvVar
|
||||||
|
}
|
||||||
|
return current, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// WorkspaceOverridden returns the name of the currently configured workspace,
|
// WorkspaceOverridden returns the name of the currently configured workspace,
|
||||||
|
|
|
@ -101,7 +101,11 @@ func (m *Meta) Backend(opts *BackendOpts) (backend.Enhanced, tfdiags.Diagnostics
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup the CLI opts we pass into backends that support it.
|
// Setup the CLI opts we pass into backends that support it.
|
||||||
cliOpts := m.backendCLIOpts()
|
cliOpts, err := m.backendCLIOpts()
|
||||||
|
if err != nil {
|
||||||
|
diags = diags.Append(err)
|
||||||
|
return nil, diags
|
||||||
|
}
|
||||||
cliOpts.Validation = true
|
cliOpts.Validation = true
|
||||||
|
|
||||||
// If the backend supports CLI initialization, do it.
|
// If the backend supports CLI initialization, do it.
|
||||||
|
@ -180,7 +184,10 @@ func (m *Meta) selectWorkspace(b backend.Backend) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the currently selected workspace.
|
// Get the currently selected workspace.
|
||||||
workspace := m.Workspace()
|
workspace, err := m.Workspace()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// Check if any of the existing workspaces matches the selected
|
// Check if any of the existing workspaces matches the selected
|
||||||
// workspace and create a numbered list of existing workspaces.
|
// workspace and create a numbered list of existing workspaces.
|
||||||
|
@ -249,7 +256,11 @@ func (m *Meta) BackendForPlan(settings plans.Backend) (backend.Enhanced, tfdiags
|
||||||
|
|
||||||
// If the backend supports CLI initialization, do it.
|
// If the backend supports CLI initialization, do it.
|
||||||
if cli, ok := b.(backend.CLI); ok {
|
if cli, ok := b.(backend.CLI); ok {
|
||||||
cliOpts := m.backendCLIOpts()
|
cliOpts, err := m.backendCLIOpts()
|
||||||
|
if err != nil {
|
||||||
|
diags = diags.Append(err)
|
||||||
|
return nil, diags
|
||||||
|
}
|
||||||
if err := cli.CLIInit(cliOpts); err != nil {
|
if err := cli.CLIInit(cliOpts); err != nil {
|
||||||
diags = diags.Append(fmt.Errorf(
|
diags = diags.Append(fmt.Errorf(
|
||||||
"Error initializing backend %T: %s\n\n"+
|
"Error initializing backend %T: %s\n\n"+
|
||||||
|
@ -270,7 +281,11 @@ func (m *Meta) BackendForPlan(settings plans.Backend) (backend.Enhanced, tfdiags
|
||||||
// Otherwise, we'll wrap our state-only remote backend in the local backend
|
// Otherwise, we'll wrap our state-only remote backend in the local backend
|
||||||
// to cause any operations to be run locally.
|
// to cause any operations to be run locally.
|
||||||
log.Printf("[TRACE] Meta.Backend: backend %T does not support operations, so wrapping it in a local backend", b)
|
log.Printf("[TRACE] Meta.Backend: backend %T does not support operations, so wrapping it in a local backend", b)
|
||||||
cliOpts := m.backendCLIOpts()
|
cliOpts, err := m.backendCLIOpts()
|
||||||
|
if err != nil {
|
||||||
|
diags = diags.Append(err)
|
||||||
|
return nil, diags
|
||||||
|
}
|
||||||
cliOpts.Validation = false // don't validate here in case config contains file(...) calls where the file doesn't exist
|
cliOpts.Validation = false // don't validate here in case config contains file(...) calls where the file doesn't exist
|
||||||
local := backendLocal.NewWithBackend(b)
|
local := backendLocal.NewWithBackend(b)
|
||||||
if err := local.CLIInit(cliOpts); err != nil {
|
if err := local.CLIInit(cliOpts); err != nil {
|
||||||
|
@ -283,7 +298,11 @@ func (m *Meta) BackendForPlan(settings plans.Backend) (backend.Enhanced, tfdiags
|
||||||
|
|
||||||
// backendCLIOpts returns a backend.CLIOpts object that should be passed to
|
// backendCLIOpts returns a backend.CLIOpts object that should be passed to
|
||||||
// a backend that supports local CLI operations.
|
// a backend that supports local CLI operations.
|
||||||
func (m *Meta) backendCLIOpts() *backend.CLIOpts {
|
func (m *Meta) backendCLIOpts() (*backend.CLIOpts, error) {
|
||||||
|
contextOpts, err := m.contextOpts()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
return &backend.CLIOpts{
|
return &backend.CLIOpts{
|
||||||
CLI: m.Ui,
|
CLI: m.Ui,
|
||||||
CLIColor: m.Colorize(),
|
CLIColor: m.Colorize(),
|
||||||
|
@ -291,10 +310,10 @@ func (m *Meta) backendCLIOpts() *backend.CLIOpts {
|
||||||
StatePath: m.statePath,
|
StatePath: m.statePath,
|
||||||
StateOutPath: m.stateOutPath,
|
StateOutPath: m.stateOutPath,
|
||||||
StateBackupPath: m.backupPath,
|
StateBackupPath: m.backupPath,
|
||||||
ContextOpts: m.contextOpts(),
|
ContextOpts: contextOpts,
|
||||||
Input: m.Input(),
|
Input: m.Input(),
|
||||||
RunningInAutomation: m.RunningInAutomation,
|
RunningInAutomation: m.RunningInAutomation,
|
||||||
}
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsLocalBackend returns true if the backend is a local backend. We use this
|
// IsLocalBackend returns true if the backend is a local backend. We use this
|
||||||
|
@ -318,7 +337,13 @@ func (m *Meta) IsLocalBackend(b backend.Backend) bool {
|
||||||
// be called.
|
// be called.
|
||||||
func (m *Meta) Operation(b backend.Backend) *backend.Operation {
|
func (m *Meta) Operation(b backend.Backend) *backend.Operation {
|
||||||
schema := b.ConfigSchema()
|
schema := b.ConfigSchema()
|
||||||
workspace := m.Workspace()
|
workspace, err := m.Workspace()
|
||||||
|
if err != nil {
|
||||||
|
// An invalid workspace error would have been raised when creating the
|
||||||
|
// backend, and the caller should have already exited. Seeing the error
|
||||||
|
// here first is a bug, so panic.
|
||||||
|
panic(fmt.Sprintf("invalid workspace: %s", err))
|
||||||
|
}
|
||||||
planOutBackend, err := m.backendState.ForPlan(schema, workspace)
|
planOutBackend, err := m.backendState.ForPlan(schema, workspace)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Always indicates an implementation error in practice, because
|
// Always indicates an implementation error in practice, because
|
||||||
|
|
|
@ -180,7 +180,10 @@ func (m *Meta) backendMigrateState_S_S(opts *backendMigrateOpts) error {
|
||||||
func (m *Meta) backendMigrateState_S_s(opts *backendMigrateOpts) error {
|
func (m *Meta) backendMigrateState_S_s(opts *backendMigrateOpts) error {
|
||||||
log.Printf("[TRACE] backendMigrateState: target backend type %q does not support named workspaces", opts.TwoType)
|
log.Printf("[TRACE] backendMigrateState: target backend type %q does not support named workspaces", opts.TwoType)
|
||||||
|
|
||||||
currentEnv := m.Workspace()
|
currentEnv, err := m.Workspace()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
migrate := opts.force
|
migrate := opts.force
|
||||||
if !migrate {
|
if !migrate {
|
||||||
|
@ -261,9 +264,12 @@ func (m *Meta) backendMigrateState_s_s(opts *backendMigrateOpts) error {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ignore invalid workspace name as it is irrelevant in this context.
|
||||||
|
workspace, _ := m.Workspace()
|
||||||
|
|
||||||
// If the currently selected workspace is the default workspace, then set
|
// If the currently selected workspace is the default workspace, then set
|
||||||
// the named workspace as the new selected workspace.
|
// the named workspace as the new selected workspace.
|
||||||
if m.Workspace() == backend.DefaultStateName {
|
if workspace == backend.DefaultStateName {
|
||||||
if err := m.SetWorkspace(opts.twoEnv); err != nil {
|
if err := m.SetWorkspace(opts.twoEnv); err != nil {
|
||||||
return nil, fmt.Errorf("Failed to set new workspace: %s", err)
|
return nil, fmt.Errorf("Failed to set new workspace: %s", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1002,7 +1002,11 @@ func TestMetaBackend_configuredChangeCopy_multiToSingle(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify we are now in the default env, or we may not be able to access the new backend
|
// Verify we are now in the default env, or we may not be able to access the new backend
|
||||||
if env := m.Workspace(); env != backend.DefaultStateName {
|
env, err := m.Workspace()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if env != backend.DefaultStateName {
|
||||||
t.Fatal("using non-default env with single-env backend")
|
t.Fatal("using non-default env with single-env backend")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -170,7 +170,10 @@ func TestMeta_Env(t *testing.T) {
|
||||||
|
|
||||||
m := new(Meta)
|
m := new(Meta)
|
||||||
|
|
||||||
env := m.Workspace()
|
env, err := m.Workspace()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
if env != backend.DefaultStateName {
|
if env != backend.DefaultStateName {
|
||||||
t.Fatalf("expected env %q, got env %q", backend.DefaultStateName, env)
|
t.Fatalf("expected env %q, got env %q", backend.DefaultStateName, env)
|
||||||
|
@ -181,7 +184,7 @@ func TestMeta_Env(t *testing.T) {
|
||||||
t.Fatal("error setting env:", err)
|
t.Fatal("error setting env:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
env = m.Workspace()
|
env, _ = m.Workspace()
|
||||||
if env != testEnv {
|
if env != testEnv {
|
||||||
t.Fatalf("expected env %q, got env %q", testEnv, env)
|
t.Fatalf("expected env %q, got env %q", testEnv, env)
|
||||||
}
|
}
|
||||||
|
@ -190,12 +193,51 @@ func TestMeta_Env(t *testing.T) {
|
||||||
t.Fatal("error setting env:", err)
|
t.Fatal("error setting env:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
env = m.Workspace()
|
env, _ = m.Workspace()
|
||||||
if env != backend.DefaultStateName {
|
if env != backend.DefaultStateName {
|
||||||
t.Fatalf("expected env %q, got env %q", backend.DefaultStateName, env)
|
t.Fatalf("expected env %q, got env %q", backend.DefaultStateName, env)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMeta_Workspace_override(t *testing.T) {
|
||||||
|
defer func(value string) {
|
||||||
|
os.Setenv(WorkspaceNameEnvVar, value)
|
||||||
|
}(os.Getenv(WorkspaceNameEnvVar))
|
||||||
|
|
||||||
|
m := new(Meta)
|
||||||
|
|
||||||
|
testCases := map[string]struct {
|
||||||
|
workspace string
|
||||||
|
err error
|
||||||
|
}{
|
||||||
|
"": {
|
||||||
|
"default",
|
||||||
|
nil,
|
||||||
|
},
|
||||||
|
"development": {
|
||||||
|
"development",
|
||||||
|
nil,
|
||||||
|
},
|
||||||
|
"invalid name": {
|
||||||
|
"",
|
||||||
|
invalidWorkspaceNameEnvVar,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, tc := range testCases {
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
os.Setenv(WorkspaceNameEnvVar, name)
|
||||||
|
workspace, err := m.Workspace()
|
||||||
|
if workspace != tc.workspace {
|
||||||
|
t.Errorf("Unexpected workspace\n got: %s\nwant: %s\n", workspace, tc.workspace)
|
||||||
|
}
|
||||||
|
if err != tc.err {
|
||||||
|
t.Errorf("Unexpected error\n got: %s\nwant: %s\n", err, tc.err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestMeta_process(t *testing.T) {
|
func TestMeta_process(t *testing.T) {
|
||||||
test = false
|
test = false
|
||||||
defer func() { test = true }()
|
defer func() { test = true }()
|
||||||
|
|
|
@ -64,7 +64,11 @@ func (c *OutputCommand) Run(args []string) int {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
env := c.Workspace()
|
env, err := c.Workspace()
|
||||||
|
if err != nil {
|
||||||
|
c.Ui.Error(fmt.Sprintf("Error selecting workspace: %s", err))
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
// Get the state
|
// Get the state
|
||||||
stateStore, err := b.StateMgr(env)
|
stateStore, err := b.StateMgr(env)
|
||||||
|
|
|
@ -135,7 +135,12 @@ func (c *PlanCommand) Run(args []string) int {
|
||||||
}
|
}
|
||||||
var backendForPlan plans.Backend
|
var backendForPlan plans.Backend
|
||||||
backendForPlan.Type = backendPseudoState.Type
|
backendForPlan.Type = backendPseudoState.Type
|
||||||
backendForPlan.Workspace = c.Workspace()
|
workspace, err := c.Workspace()
|
||||||
|
if err != nil {
|
||||||
|
c.Ui.Error(fmt.Sprintf("Error selecting workspace: %s", err))
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
backendForPlan.Workspace = workspace
|
||||||
|
|
||||||
// Configuration is a little more awkward to handle here because it's
|
// Configuration is a little more awkward to handle here because it's
|
||||||
// stored in state as raw JSON but we need it as a plans.DynamicValue
|
// stored in state as raw JSON but we need it as a plans.DynamicValue
|
||||||
|
|
|
@ -83,7 +83,11 @@ func (c *ProvidersCommand) Run(args []string) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the state
|
// Get the state
|
||||||
env := c.Workspace()
|
env, err := c.Workspace()
|
||||||
|
if err != nil {
|
||||||
|
c.Ui.Error(fmt.Sprintf("Error selecting workspace: %s", err))
|
||||||
|
return 1
|
||||||
|
}
|
||||||
s, err := b.StateMgr(env)
|
s, err := b.StateMgr(env)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Ui.Error(fmt.Sprintf("Failed to load state: %s", err))
|
c.Ui.Error(fmt.Sprintf("Failed to load state: %s", err))
|
||||||
|
|
|
@ -130,7 +130,11 @@ func (c *ShowCommand) Run(args []string) int {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
env := c.Workspace()
|
env, err := c.Workspace()
|
||||||
|
if err != nil {
|
||||||
|
c.Ui.Error(fmt.Sprintf("Error selecting workspace: %s", err))
|
||||||
|
return 1
|
||||||
|
}
|
||||||
stateFile, stateErr = getStateFromEnv(b, env)
|
stateFile, stateErr = getStateFromEnv(b, env)
|
||||||
if stateErr != nil {
|
if stateErr != nil {
|
||||||
c.Ui.Error(stateErr.Error())
|
c.Ui.Error(stateErr.Error())
|
||||||
|
|
|
@ -41,7 +41,11 @@ func (c *StateListCommand) Run(args []string) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the state
|
// Get the state
|
||||||
env := c.Workspace()
|
env, err := c.Workspace()
|
||||||
|
if err != nil {
|
||||||
|
c.Ui.Error(fmt.Sprintf("Error selecting workspace: %s", err))
|
||||||
|
return 1
|
||||||
|
}
|
||||||
stateMgr, err := b.StateMgr(env)
|
stateMgr, err := b.StateMgr(env)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Ui.Error(fmt.Sprintf(errStateLoadingState, err))
|
c.Ui.Error(fmt.Sprintf(errStateLoadingState, err))
|
||||||
|
|
|
@ -37,7 +37,10 @@ func (c *StateMeta) State() (statemgr.Full, error) {
|
||||||
return nil, backendDiags.Err()
|
return nil, backendDiags.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
workspace := c.Workspace()
|
workspace, err := c.Workspace()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
// Get the state
|
// Get the state
|
||||||
s, err := b.StateMgr(workspace)
|
s, err := b.StateMgr(workspace)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -32,7 +32,11 @@ func (c *StatePullCommand) Run(args []string) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the state manager for the current workspace
|
// Get the state manager for the current workspace
|
||||||
env := c.Workspace()
|
env, err := c.Workspace()
|
||||||
|
if err != nil {
|
||||||
|
c.Ui.Error(fmt.Sprintf("Error selecting workspace: %s", err))
|
||||||
|
return 1
|
||||||
|
}
|
||||||
stateMgr, err := b.StateMgr(env)
|
stateMgr, err := b.StateMgr(env)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Ui.Error(fmt.Sprintf(errStateLoadingState, err))
|
c.Ui.Error(fmt.Sprintf(errStateLoadingState, err))
|
||||||
|
|
|
@ -72,7 +72,11 @@ func (c *StatePushCommand) Run(args []string) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the state manager for the currently-selected workspace
|
// Get the state manager for the currently-selected workspace
|
||||||
env := c.Workspace()
|
env, err := c.Workspace()
|
||||||
|
if err != nil {
|
||||||
|
c.Ui.Error(fmt.Sprintf("Error selecting workspace: %s", err))
|
||||||
|
return 1
|
||||||
|
}
|
||||||
stateMgr, err := b.StateMgr(env)
|
stateMgr, err := b.StateMgr(env)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Ui.Error(fmt.Sprintf("Failed to load destination state: %s", err))
|
c.Ui.Error(fmt.Sprintf("Failed to load destination state: %s", err))
|
||||||
|
|
|
@ -89,7 +89,11 @@ func (c *StateShowCommand) Run(args []string) int {
|
||||||
schemas := ctx.Schemas()
|
schemas := ctx.Schemas()
|
||||||
|
|
||||||
// Get the state
|
// Get the state
|
||||||
env := c.Workspace()
|
env, err := c.Workspace()
|
||||||
|
if err != nil {
|
||||||
|
c.Ui.Error(fmt.Sprintf("Error selecting workspace: %s", err))
|
||||||
|
return 1
|
||||||
|
}
|
||||||
stateMgr, err := b.StateMgr(env)
|
stateMgr, err := b.StateMgr(env)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Ui.Error(fmt.Sprintf(errStateLoadingState, err))
|
c.Ui.Error(fmt.Sprintf(errStateLoadingState, err))
|
||||||
|
|
|
@ -71,7 +71,11 @@ func (c *TaintCommand) Run(args []string) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the state
|
// Get the state
|
||||||
env := c.Workspace()
|
env, err := c.Workspace()
|
||||||
|
if err != nil {
|
||||||
|
c.Ui.Error(fmt.Sprintf("Error selecting workspace: %s", err))
|
||||||
|
return 1
|
||||||
|
}
|
||||||
stateMgr, err := b.StateMgr(env)
|
stateMgr, err := b.StateMgr(env)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Ui.Error(fmt.Sprintf("Failed to load state: %s", err))
|
c.Ui.Error(fmt.Sprintf("Failed to load state: %s", err))
|
||||||
|
|
|
@ -65,7 +65,11 @@ func (c *UnlockCommand) Run(args []string) int {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
env := c.Workspace()
|
env, err := c.Workspace()
|
||||||
|
if err != nil {
|
||||||
|
c.Ui.Error(fmt.Sprintf("Error selecting workspace: %s", err))
|
||||||
|
return 1
|
||||||
|
}
|
||||||
stateMgr, err := b.StateMgr(env)
|
stateMgr, err := b.StateMgr(env)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Ui.Error(fmt.Sprintf("Failed to load state: %s", err))
|
c.Ui.Error(fmt.Sprintf("Failed to load state: %s", err))
|
||||||
|
|
|
@ -66,7 +66,11 @@ func (c *UntaintCommand) Run(args []string) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the state
|
// Get the state
|
||||||
workspace := c.Workspace()
|
workspace, err := c.Workspace()
|
||||||
|
if err != nil {
|
||||||
|
c.Ui.Error(fmt.Sprintf("Error selecting workspace: %s", err))
|
||||||
|
return 1
|
||||||
|
}
|
||||||
stateMgr, err := b.StateMgr(workspace)
|
stateMgr, err := b.StateMgr(workspace)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Ui.Error(fmt.Sprintf("Failed to load state: %s", err))
|
c.Ui.Error(fmt.Sprintf("Failed to load state: %s", err))
|
||||||
|
|
|
@ -110,7 +110,11 @@ func (c *ValidateCommand) validate(dir string) tfdiags.Diagnostics {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
opts := c.contextOpts()
|
opts, err := c.contextOpts()
|
||||||
|
if err != nil {
|
||||||
|
diags = diags.Append(err)
|
||||||
|
return diags
|
||||||
|
}
|
||||||
opts.Config = cfg
|
opts.Config = cfg
|
||||||
opts.Variables = varValues
|
opts.Variables = varValues
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ func TestWorkspace_createAndChange(t *testing.T) {
|
||||||
|
|
||||||
newCmd := &WorkspaceNewCommand{}
|
newCmd := &WorkspaceNewCommand{}
|
||||||
|
|
||||||
current := newCmd.Workspace()
|
current, _ := newCmd.Workspace()
|
||||||
if current != backend.DefaultStateName {
|
if current != backend.DefaultStateName {
|
||||||
t.Fatal("current workspace should be 'default'")
|
t.Fatal("current workspace should be 'default'")
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ func TestWorkspace_createAndChange(t *testing.T) {
|
||||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
||||||
}
|
}
|
||||||
|
|
||||||
current = newCmd.Workspace()
|
current, _ = newCmd.Workspace()
|
||||||
if current != "test" {
|
if current != "test" {
|
||||||
t.Fatalf("current workspace should be 'test', got %q", current)
|
t.Fatalf("current workspace should be 'test', got %q", current)
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ func TestWorkspace_createAndChange(t *testing.T) {
|
||||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
|
||||||
}
|
}
|
||||||
|
|
||||||
current = newCmd.Workspace()
|
current, _ = newCmd.Workspace()
|
||||||
if current != backend.DefaultStateName {
|
if current != backend.DefaultStateName {
|
||||||
t.Fatal("current workspace should be 'default'")
|
t.Fatal("current workspace should be 'default'")
|
||||||
}
|
}
|
||||||
|
@ -307,7 +307,7 @@ func TestWorkspace_delete(t *testing.T) {
|
||||||
Meta: Meta{Ui: ui},
|
Meta: Meta{Ui: ui},
|
||||||
}
|
}
|
||||||
|
|
||||||
current := delCmd.Workspace()
|
current, _ := delCmd.Workspace()
|
||||||
if current != "test" {
|
if current != "test" {
|
||||||
t.Fatal("wrong workspace:", current)
|
t.Fatal("wrong workspace:", current)
|
||||||
}
|
}
|
||||||
|
@ -330,7 +330,7 @@ func TestWorkspace_delete(t *testing.T) {
|
||||||
t.Fatalf("error deleting workspace: %s", ui.ErrorWriter)
|
t.Fatalf("error deleting workspace: %s", ui.ErrorWriter)
|
||||||
}
|
}
|
||||||
|
|
||||||
current = delCmd.Workspace()
|
current, _ = delCmd.Workspace()
|
||||||
if current != backend.DefaultStateName {
|
if current != backend.DefaultStateName {
|
||||||
t.Fatalf("wrong workspace: %q", current)
|
t.Fatalf("wrong workspace: %q", current)
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,7 +91,12 @@ func (c *WorkspaceDeleteCommand) Run(args []string) int {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
if workspace == c.Workspace() {
|
currentWorkspace, err := c.Workspace()
|
||||||
|
if err != nil {
|
||||||
|
c.Ui.Error(fmt.Sprintf("Error selecting workspace: %s", err))
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
if workspace == currentWorkspace {
|
||||||
c.Ui.Error(fmt.Sprintf(strings.TrimSpace(envDelCurrent), workspace))
|
c.Ui.Error(fmt.Sprintf(strings.TrimSpace(envDelCurrent), workspace))
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,11 @@ func (c *WorkspaceShowCommand) Run(args []string) int {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
workspace := c.Workspace()
|
workspace, err := c.Workspace()
|
||||||
|
if err != nil {
|
||||||
|
c.Ui.Error(fmt.Sprintf("Error selecting workspace: %s", err))
|
||||||
|
return 1
|
||||||
|
}
|
||||||
c.Ui.Output(workspace)
|
c.Ui.Output(workspace)
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
Loading…
Reference in New Issue