mirror of
https://github.com/hashicorp/terraform.git
synced 2026-05-28 04:03:27 -04:00
PSS: Update how commands access backends, so both backend and state_store configuration can be used (#37569)
Some checks are pending
build / Determine intended Terraform version (push) Waiting to run
build / Determine Go toolchain version (push) Waiting to run
build / Generate release metadata (push) Blocked by required conditions
build / Build for freebsd_386 (push) Blocked by required conditions
build / Build for linux_386 (push) Blocked by required conditions
build / Build for openbsd_386 (push) Blocked by required conditions
build / Build for windows_386 (push) Blocked by required conditions
build / Build for darwin_amd64 (push) Blocked by required conditions
build / Build for freebsd_amd64 (push) Blocked by required conditions
build / Build for linux_amd64 (push) Blocked by required conditions
build / Build for openbsd_amd64 (push) Blocked by required conditions
build / Build for solaris_amd64 (push) Blocked by required conditions
build / Build for windows_amd64 (push) Blocked by required conditions
build / Build for freebsd_arm (push) Blocked by required conditions
build / Build for linux_arm (push) Blocked by required conditions
build / Build for darwin_arm64 (push) Blocked by required conditions
build / Build for linux_arm64 (push) Blocked by required conditions
build / Build for windows_arm64 (push) Blocked by required conditions
build / Build Docker image for linux_386 (push) Blocked by required conditions
build / Build Docker image for linux_amd64 (push) Blocked by required conditions
build / Build Docker image for linux_arm (push) Blocked by required conditions
build / Build Docker image for linux_arm64 (push) Blocked by required conditions
build / Build e2etest for linux_386 (push) Blocked by required conditions
build / Build e2etest for windows_386 (push) Blocked by required conditions
build / Build e2etest for darwin_amd64 (push) Blocked by required conditions
build / Build e2etest for linux_amd64 (push) Blocked by required conditions
build / Build e2etest for windows_amd64 (push) Blocked by required conditions
build / Build e2etest for linux_arm (push) Blocked by required conditions
build / Build e2etest for darwin_arm64 (push) Blocked by required conditions
build / Build e2etest for linux_arm64 (push) Blocked by required conditions
build / Run e2e test for linux_386 (push) Blocked by required conditions
build / Run e2e test for windows_386 (push) Blocked by required conditions
build / Run e2e test for darwin_amd64 (push) Blocked by required conditions
build / Run e2e test for linux_amd64 (push) Blocked by required conditions
build / Run e2e test for windows_amd64 (push) Blocked by required conditions
build / Run e2e test for linux_arm (push) Blocked by required conditions
build / Run e2e test for linux_arm64 (push) Blocked by required conditions
build / Run terraform-exec test for linux amd64 (push) Blocked by required conditions
Quick Checks / Unit Tests (push) Waiting to run
Quick Checks / Race Tests (push) Waiting to run
Quick Checks / End-to-end Tests (push) Waiting to run
Quick Checks / Code Consistency Checks (push) Waiting to run
Some checks are pending
build / Determine intended Terraform version (push) Waiting to run
build / Determine Go toolchain version (push) Waiting to run
build / Generate release metadata (push) Blocked by required conditions
build / Build for freebsd_386 (push) Blocked by required conditions
build / Build for linux_386 (push) Blocked by required conditions
build / Build for openbsd_386 (push) Blocked by required conditions
build / Build for windows_386 (push) Blocked by required conditions
build / Build for darwin_amd64 (push) Blocked by required conditions
build / Build for freebsd_amd64 (push) Blocked by required conditions
build / Build for linux_amd64 (push) Blocked by required conditions
build / Build for openbsd_amd64 (push) Blocked by required conditions
build / Build for solaris_amd64 (push) Blocked by required conditions
build / Build for windows_amd64 (push) Blocked by required conditions
build / Build for freebsd_arm (push) Blocked by required conditions
build / Build for linux_arm (push) Blocked by required conditions
build / Build for darwin_arm64 (push) Blocked by required conditions
build / Build for linux_arm64 (push) Blocked by required conditions
build / Build for windows_arm64 (push) Blocked by required conditions
build / Build Docker image for linux_386 (push) Blocked by required conditions
build / Build Docker image for linux_amd64 (push) Blocked by required conditions
build / Build Docker image for linux_arm (push) Blocked by required conditions
build / Build Docker image for linux_arm64 (push) Blocked by required conditions
build / Build e2etest for linux_386 (push) Blocked by required conditions
build / Build e2etest for windows_386 (push) Blocked by required conditions
build / Build e2etest for darwin_amd64 (push) Blocked by required conditions
build / Build e2etest for linux_amd64 (push) Blocked by required conditions
build / Build e2etest for windows_amd64 (push) Blocked by required conditions
build / Build e2etest for linux_arm (push) Blocked by required conditions
build / Build e2etest for darwin_arm64 (push) Blocked by required conditions
build / Build e2etest for linux_arm64 (push) Blocked by required conditions
build / Run e2e test for linux_386 (push) Blocked by required conditions
build / Run e2e test for windows_386 (push) Blocked by required conditions
build / Run e2e test for darwin_amd64 (push) Blocked by required conditions
build / Run e2e test for linux_amd64 (push) Blocked by required conditions
build / Run e2e test for windows_amd64 (push) Blocked by required conditions
build / Run e2e test for linux_arm (push) Blocked by required conditions
build / Run e2e test for linux_arm64 (push) Blocked by required conditions
build / Run terraform-exec test for linux amd64 (push) Blocked by required conditions
Quick Checks / Unit Tests (push) Waiting to run
Quick Checks / Race Tests (push) Waiting to run
Quick Checks / End-to-end Tests (push) Waiting to run
Quick Checks / Code Consistency Checks (push) Waiting to run
* Add a generic method for loading an operations backend in non-init commands * Refactor commands to use new prepareBackend method: group 1 * Refactor commands to use new prepareBackend method: group 2, where config parsing needs to be explicitly added * Refactor commands to use new prepareBackend method: group 3, where we can use already parsed config * Additional, more nested, places where logic for accessing backends needs to be refactored * Remove duplicated comment * Add test coverage of `(m *Meta) prepareBackend()` * Add TODO related to using plans for backend/state_store config in apply commands * Add `testStateStoreMockWithChunkNegotiation` test helper * Add assertions to tests about the backend (remote-state, local, etc) in use within operations backend * Stop prepareBackend taking locks as argument * Code comment in prepareBackend * Replace c.Meta.prepareBackend with c.prepareBackend * Change `c.Meta.loadSingleModule` to `c.loadSingleModule` * Rename (Meta).prepareBackend to (Meta).backend, update godoc comment to make relationship to (Meta).Backend more obvious. * Revert change from config.Module to config.Root.Module * Update `(m *Meta) backend` method to parse config itself, and also to adhere to calling code's viewtype instructions * Update all tests and calling code following previous commit * Change how an operations backend is obtained by autocomplete code * Update autocomplete to return nil if no workspace names are returned from the backend * Add test coverage for autocompleting workspace names when using a pluggable state store * Fix output command: pass view type data to new `backend` method * Fix in plan command: pass correct view type to `backend` method * Fix `providers schema` command to use correct viewtype when preparing a backend
This commit is contained in:
parent
f0a2953bd0
commit
f5a28cfa8b
33 changed files with 420 additions and 207 deletions
|
|
@ -219,19 +219,15 @@ func (c *ApplyCommand) PrepareBackend(planFile *planfile.WrappedPlanFile, args *
|
|||
))
|
||||
return nil, diags
|
||||
}
|
||||
// TODO: Update BackendForLocalPlan to use state storage, and plan to be able to contain State Store config details
|
||||
be, beDiags = c.BackendForLocalPlan(plan.Backend)
|
||||
} else {
|
||||
// Both new plans and saved cloud plans load their backend from config.
|
||||
backendConfig, configDiags := c.loadBackendConfig(".")
|
||||
diags = diags.Append(configDiags)
|
||||
if configDiags.HasErrors() {
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
be, beDiags = c.Backend(&BackendOpts{
|
||||
BackendConfig: backendConfig,
|
||||
ViewType: viewType,
|
||||
})
|
||||
// Load the backend
|
||||
//
|
||||
// Note: Both new plans and saved cloud plans load their backend from config,
|
||||
// hence the config parsing in the method below.
|
||||
be, beDiags = c.backend(".", viewType)
|
||||
}
|
||||
|
||||
diags = diags.Append(beDiags)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/terraform/internal/command/arguments"
|
||||
"github.com/posener/complete"
|
||||
)
|
||||
|
||||
|
|
@ -48,19 +49,18 @@ func (m *Meta) completePredictWorkspaceName() complete.Predictor {
|
|||
return nil
|
||||
}
|
||||
|
||||
backendConfig, diags := m.loadBackendConfig(configPath)
|
||||
if diags.HasErrors() {
|
||||
return nil
|
||||
}
|
||||
|
||||
b, diags := m.Backend(&BackendOpts{
|
||||
BackendConfig: backendConfig,
|
||||
})
|
||||
b, diags := m.backend(configPath, arguments.ViewHuman)
|
||||
if diags.HasErrors() {
|
||||
return nil
|
||||
}
|
||||
|
||||
names, _ := b.Workspaces()
|
||||
if len(names) == 0 {
|
||||
// Presence of the "default" isn't always guaranteed
|
||||
// Backends will report it as always existing, pluggable
|
||||
// state stores will only do so if it _actually_ exists.
|
||||
return nil
|
||||
}
|
||||
return names
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,37 +4,124 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/cli"
|
||||
"github.com/hashicorp/terraform/internal/addrs"
|
||||
"github.com/hashicorp/terraform/internal/command/workdir"
|
||||
"github.com/hashicorp/terraform/internal/providers"
|
||||
"github.com/posener/complete"
|
||||
)
|
||||
|
||||
func TestMetaCompletePredictWorkspaceName(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := t.TempDir()
|
||||
os.MkdirAll(td, 0755)
|
||||
t.Chdir(td)
|
||||
|
||||
// make sure a vars file doesn't interfere
|
||||
err := ioutil.WriteFile(DefaultVarsFilename, nil, 0644)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Run("test autocompletion using the local backend", func(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := t.TempDir()
|
||||
t.Chdir(td)
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
meta := &Meta{Ui: ui}
|
||||
ui := new(cli.MockUi)
|
||||
meta := &Meta{Ui: ui}
|
||||
|
||||
predictor := meta.completePredictWorkspaceName()
|
||||
predictor := meta.completePredictWorkspaceName()
|
||||
|
||||
got := predictor.Predict(complete.Args{
|
||||
Last: "",
|
||||
got := predictor.Predict(complete.Args{
|
||||
Last: "",
|
||||
})
|
||||
want := []string{"default"}
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Errorf("wrong result\ngot: %#v\nwant: %#v", got, want)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("test autocompletion using a state store", func(t *testing.T) {
|
||||
// Create a temporary working directory with state_store config
|
||||
td := t.TempDir()
|
||||
testCopyDir(t, testFixturePath("state-store-unchanged"), td)
|
||||
t.Chdir(td)
|
||||
|
||||
// Set up pluggable state store provider mock
|
||||
mockProvider := mockPluggableStateStorageProvider()
|
||||
// Mock the existence of workspaces
|
||||
mockProvider.MockStates = map[string]interface{}{
|
||||
"default": true,
|
||||
"foobar": true,
|
||||
}
|
||||
mockProviderAddress := addrs.NewDefaultProvider("test")
|
||||
providerSource, close := newMockProviderSource(t, map[string][]string{
|
||||
"hashicorp/test": {"1.0.0"},
|
||||
})
|
||||
defer close()
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
view, _ := testView(t)
|
||||
wd := workdir.NewDir(".")
|
||||
wd.OverrideOriginalWorkingDir(td)
|
||||
meta := Meta{
|
||||
WorkingDir: wd, // Use the test's temp dir
|
||||
Ui: ui,
|
||||
View: view,
|
||||
AllowExperimentalFeatures: true,
|
||||
testingOverrides: &testingOverrides{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
mockProviderAddress: providers.FactoryFixed(mockProvider),
|
||||
},
|
||||
},
|
||||
ProviderSource: providerSource,
|
||||
}
|
||||
|
||||
predictor := meta.completePredictWorkspaceName()
|
||||
|
||||
got := predictor.Predict(complete.Args{
|
||||
Last: "",
|
||||
})
|
||||
want := []string{"default", "foobar"}
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Errorf("wrong result\ngot: %#v\nwant: %#v", got, want)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("test autocompletion using a state store containing no workspaces", func(t *testing.T) {
|
||||
// Create a temporary working directory with state_store config
|
||||
td := t.TempDir()
|
||||
testCopyDir(t, testFixturePath("state-store-unchanged"), td)
|
||||
t.Chdir(td)
|
||||
|
||||
// Set up pluggable state store provider mock
|
||||
mockProvider := mockPluggableStateStorageProvider()
|
||||
// No workspaces exist in the mock
|
||||
mockProvider.MockStates = map[string]interface{}{}
|
||||
mockProviderAddress := addrs.NewDefaultProvider("test")
|
||||
providerSource, close := newMockProviderSource(t, map[string][]string{
|
||||
"hashicorp/test": {"1.0.0"},
|
||||
})
|
||||
defer close()
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
view, _ := testView(t)
|
||||
wd := workdir.NewDir(".")
|
||||
wd.OverrideOriginalWorkingDir(td)
|
||||
meta := Meta{
|
||||
WorkingDir: wd, // Use the test's temp dir
|
||||
Ui: ui,
|
||||
View: view,
|
||||
AllowExperimentalFeatures: true,
|
||||
testingOverrides: &testingOverrides{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
mockProviderAddress: providers.FactoryFixed(mockProvider),
|
||||
},
|
||||
},
|
||||
ProviderSource: providerSource,
|
||||
}
|
||||
|
||||
predictor := meta.completePredictWorkspaceName()
|
||||
|
||||
got := predictor.Predict(complete.Args{
|
||||
Last: "",
|
||||
})
|
||||
if got != nil {
|
||||
t.Errorf("wrong result\ngot: %#v\nwant: %#v", got, nil)
|
||||
}
|
||||
})
|
||||
want := []string{"default"}
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Errorf("wrong result\ngot: %#v\nwant: %#v", got, want)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,17 +53,8 @@ func (c *ConsoleCommand) Run(args []string) int {
|
|||
|
||||
var diags tfdiags.Diagnostics
|
||||
|
||||
backendConfig, backendDiags := c.loadBackendConfig(configPath)
|
||||
diags = diags.Append(backendDiags)
|
||||
if diags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
return 1
|
||||
}
|
||||
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(&BackendOpts{
|
||||
BackendConfig: backendConfig,
|
||||
})
|
||||
b, backendDiags := c.backend(configPath, arguments.ViewHuman)
|
||||
diags = diags.Append(backendDiags)
|
||||
if backendDiags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
|
|
|
|||
|
|
@ -68,17 +68,8 @@ func (c *GraphCommand) Run(args []string) int {
|
|||
|
||||
var diags tfdiags.Diagnostics
|
||||
|
||||
backendConfig, backendDiags := c.loadBackendConfig(configPath)
|
||||
diags = diags.Append(backendDiags)
|
||||
if diags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
return 1
|
||||
}
|
||||
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(&BackendOpts{
|
||||
BackendConfig: backendConfig,
|
||||
})
|
||||
b, backendDiags := c.backend(".", arguments.ViewHuman)
|
||||
diags = diags.Append(backendDiags)
|
||||
if backendDiags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
|
|
|
|||
|
|
@ -164,9 +164,7 @@ func (c *ImportCommand) Run(args []string) int {
|
|||
}
|
||||
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(&BackendOpts{
|
||||
BackendConfig: config.Module.Backend,
|
||||
})
|
||||
b, backendDiags := c.backend(".", arguments.ViewHuman)
|
||||
diags = diags.Append(backendDiags)
|
||||
if backendDiags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
|
|
|
|||
|
|
@ -1580,6 +1580,82 @@ func (m *Meta) updateSavedBackendHash(cHash int, sMgr *clistate.LocalState) tfdi
|
|||
return diags
|
||||
}
|
||||
|
||||
// backend returns an operations backend that may use a backend, cloud, or state_store block for state storage.
|
||||
// Based on the supplied config, it prepares arguments to pass into (Meta).Backend, which returns the operations backend.
|
||||
//
|
||||
// This method should be used in NON-init operations only; it's incapable of processing new init command CLI flags used
|
||||
// for partial configuration, however it will use the backend state file to use partial configuration from a previous
|
||||
// init command.
|
||||
func (m *Meta) backend(configPath string, viewType arguments.ViewType) (backendrun.OperationsBackend, tfdiags.Diagnostics) {
|
||||
var diags tfdiags.Diagnostics
|
||||
|
||||
if configPath == "" {
|
||||
configPath = "."
|
||||
}
|
||||
|
||||
// Only return error diagnostics at this point. Any warnings will be caught
|
||||
// again later and duplicated in the output.
|
||||
root, mDiags := m.loadSingleModule(configPath)
|
||||
if mDiags.HasErrors() {
|
||||
diags = diags.Append(mDiags)
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
var opts *BackendOpts
|
||||
switch {
|
||||
case root.Backend != nil:
|
||||
opts = &BackendOpts{
|
||||
BackendConfig: root.Backend,
|
||||
ViewType: viewType,
|
||||
}
|
||||
case root.CloudConfig != nil:
|
||||
backendConfig := root.CloudConfig.ToBackendConfig()
|
||||
opts = &BackendOpts{
|
||||
BackendConfig: &backendConfig,
|
||||
ViewType: viewType,
|
||||
}
|
||||
case root.StateStore != nil:
|
||||
// In addition to config, use of a state_store requires
|
||||
// provider factory and provider locks data
|
||||
locks, lDiags := m.lockedDependencies()
|
||||
diags = diags.Append(lDiags)
|
||||
if lDiags.HasErrors() {
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
factory, fDiags := m.GetStateStoreProviderFactory(root.StateStore, locks)
|
||||
diags = diags.Append(fDiags)
|
||||
if fDiags.HasErrors() {
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
opts = &BackendOpts{
|
||||
StateStoreConfig: root.StateStore,
|
||||
ProviderFactory: factory,
|
||||
Locks: locks,
|
||||
ViewType: viewType,
|
||||
}
|
||||
default:
|
||||
// there is no config; defaults to local state storage
|
||||
opts = &BackendOpts{
|
||||
ViewType: viewType,
|
||||
}
|
||||
}
|
||||
|
||||
// This method should not be used for init commands,
|
||||
// so we always set this value as false.
|
||||
opts.Init = false
|
||||
|
||||
// Load the backend
|
||||
be, beDiags := m.Backend(opts)
|
||||
diags = diags.Append(beDiags)
|
||||
if beDiags.HasErrors() {
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
return be, diags
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// State Store Config Scenarios
|
||||
// The functions below cover handling all the various scenarios that
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import (
|
|||
"github.com/hashicorp/terraform/internal/addrs"
|
||||
"github.com/hashicorp/terraform/internal/backend"
|
||||
"github.com/hashicorp/terraform/internal/cloud"
|
||||
"github.com/hashicorp/terraform/internal/command/arguments"
|
||||
"github.com/hashicorp/terraform/internal/command/clistate"
|
||||
"github.com/hashicorp/terraform/internal/command/workdir"
|
||||
"github.com/hashicorp/terraform/internal/configs"
|
||||
|
|
@ -2962,6 +2963,126 @@ func Test_getStateStorageProviderVersion(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestMetaBackend_prepareBackend(t *testing.T) {
|
||||
|
||||
t.Run("it returns a cloud backend from cloud backend config", func(t *testing.T) {
|
||||
// Create a temporary working directory with cloud configuration in
|
||||
td := t.TempDir()
|
||||
testCopyDir(t, testFixturePath("cloud-config"), td)
|
||||
t.Chdir(td)
|
||||
|
||||
m := testMetaBackend(t, nil)
|
||||
|
||||
// We cannot initialize a cloud backend so we instead check
|
||||
// the init error is referencing HCP Terraform
|
||||
_, bDiags := m.backend(td, arguments.ViewHuman)
|
||||
if !bDiags.HasErrors() {
|
||||
t.Fatal("expected error but got none")
|
||||
}
|
||||
wantErr := "HCP Terraform or Terraform Enterprise initialization required: please run \"terraform init\""
|
||||
if !strings.Contains(bDiags.Err().Error(), wantErr) {
|
||||
t.Fatalf("expected error to contain %q, but got: %q",
|
||||
wantErr,
|
||||
bDiags.Err())
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("it returns a backend from backend config", func(t *testing.T) {
|
||||
// Create a temporary working directory with backend configuration in
|
||||
td := t.TempDir()
|
||||
testCopyDir(t, testFixturePath("backend-unchanged"), td)
|
||||
t.Chdir(td)
|
||||
|
||||
m := testMetaBackend(t, nil)
|
||||
|
||||
b, bDiags := m.backend(td, arguments.ViewHuman)
|
||||
if bDiags.HasErrors() {
|
||||
t.Fatal("unexpected error: ", bDiags.Err())
|
||||
}
|
||||
|
||||
if _, ok := b.(*local.Local); !ok {
|
||||
t.Fatal("expected returned operations backend to be a Local backend")
|
||||
}
|
||||
// Check the type of backend inside the Local via schema
|
||||
// In this case a `local` backend should have been returned by default.
|
||||
//
|
||||
// Look for the path attribute.
|
||||
schema := b.ConfigSchema()
|
||||
if _, ok := schema.Attributes["path"]; !ok {
|
||||
t.Fatalf("expected the operations backend to report the schema of a local backend, but got something unexpected: %#v", schema)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("it returns a local backend when there is empty configuration", func(t *testing.T) {
|
||||
td := t.TempDir()
|
||||
testCopyDir(t, testFixturePath("empty"), td)
|
||||
t.Chdir(td)
|
||||
|
||||
m := testMetaBackend(t, nil)
|
||||
b, bDiags := m.backend(td, arguments.ViewHuman)
|
||||
if bDiags.HasErrors() {
|
||||
t.Fatal("unexpected error: ", bDiags.Err())
|
||||
}
|
||||
|
||||
if _, ok := b.(*local.Local); !ok {
|
||||
t.Fatal("expected returned operations backend to be a Local backend")
|
||||
}
|
||||
// Check the type of backend inside the Local via schema
|
||||
// In this case a `local` backend should have been returned by default.
|
||||
//
|
||||
// Look for the path attribute.
|
||||
schema := b.ConfigSchema()
|
||||
if _, ok := schema.Attributes["path"]; !ok {
|
||||
t.Fatalf("expected the operations backend to report the schema of a local backend, but got something unexpected: %#v", schema)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("it returns a state_store from state_store config", func(t *testing.T) {
|
||||
// Create a temporary working directory with backend configuration in
|
||||
td := t.TempDir()
|
||||
testCopyDir(t, testFixturePath("state-store-unchanged"), td)
|
||||
t.Chdir(td)
|
||||
|
||||
m := testMetaBackend(t, nil)
|
||||
m.AllowExperimentalFeatures = true
|
||||
mock := testStateStoreMockWithChunkNegotiation(t, 12345) // chunk size needs to be set, value is arbitrary
|
||||
m.testingOverrides = &testingOverrides{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): providers.FactoryFixed(mock),
|
||||
},
|
||||
}
|
||||
|
||||
// Prepare appropriate locks; config uses a hashicorp/test provider @ v1.2.3
|
||||
locks := depsfile.NewLocks()
|
||||
providerAddr := addrs.MustParseProviderSourceString("registry.terraform.io/hashicorp/test")
|
||||
constraint, err := providerreqs.ParseVersionConstraints(">1.0.0")
|
||||
if err != nil {
|
||||
t.Fatalf("test setup failed when making constraint: %s", err)
|
||||
}
|
||||
locks.SetProvider(
|
||||
providerAddr,
|
||||
versions.MustParseVersion("1.2.3"),
|
||||
constraint,
|
||||
[]providerreqs.Hash{""},
|
||||
)
|
||||
|
||||
b, bDiags := m.backend(td, arguments.ViewHuman)
|
||||
if bDiags.HasErrors() {
|
||||
t.Fatalf("unexpected error: %s", bDiags.Err())
|
||||
}
|
||||
|
||||
if _, ok := b.(*local.Local); !ok {
|
||||
t.Fatal("expected returned operations backend to be a Local backend")
|
||||
}
|
||||
// Check the state_store inside the Local via schema
|
||||
// Look for the mock state_store's attribute called `value`.
|
||||
schema := b.ConfigSchema()
|
||||
if _, ok := schema.Attributes["value"]; !ok {
|
||||
t.Fatalf("expected the operations backend to report the schema of the state_store, but got something unexpected: %#v", schema)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func testMetaBackend(t *testing.T, args []string) *Meta {
|
||||
var m Meta
|
||||
m.Ui = new(cli.MockUi)
|
||||
|
|
@ -3011,6 +3132,21 @@ func testStateStoreMock(t *testing.T) *testing_provider.MockProvider {
|
|||
}
|
||||
}
|
||||
|
||||
// testStateStoreMockWithChunkNegotiation is just like testStateStoreMock but the returned mock is set up so it'll be configured
|
||||
// without this error: `Failed to negotiate acceptable chunk size`
|
||||
//
|
||||
// This is meant to be a convenience method when a test is definitely not testing anything related to state store configuration.
|
||||
func testStateStoreMockWithChunkNegotiation(t *testing.T, chunkSize int64) *testing_provider.MockProvider {
|
||||
t.Helper()
|
||||
mock := testStateStoreMock(t)
|
||||
mock.ConfigureStateStoreResponse = &providers.ConfigureStateStoreResponse{
|
||||
Capabilities: providers.StateStoreServerCapabilities{
|
||||
ChunkSize: chunkSize,
|
||||
},
|
||||
}
|
||||
return mock
|
||||
}
|
||||
|
||||
func configBodyForTest(t *testing.T, config string) hcl.Body {
|
||||
t.Helper()
|
||||
f, diags := hclsyntax.ParseConfig([]byte(config), "", hcl.Pos{Line: 1, Column: 1})
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ func (c *OutputCommand) Run(rawArgs []string) int {
|
|||
view := views.NewOutput(args.ViewType, c.View)
|
||||
|
||||
// Fetch data from state
|
||||
outputs, diags := c.Outputs(args.StatePath)
|
||||
outputs, diags := c.Outputs(args.StatePath, args.ViewType)
|
||||
if diags.HasErrors() {
|
||||
view.Diagnostics(diags)
|
||||
return 1
|
||||
|
|
@ -54,7 +54,7 @@ func (c *OutputCommand) Run(rawArgs []string) int {
|
|||
return 0
|
||||
}
|
||||
|
||||
func (c *OutputCommand) Outputs(statePath string) (map[string]*states.OutputValue, tfdiags.Diagnostics) {
|
||||
func (c *OutputCommand) Outputs(statePath string, view arguments.ViewType) (map[string]*states.OutputValue, tfdiags.Diagnostics) {
|
||||
var diags tfdiags.Diagnostics
|
||||
|
||||
// Allow state path override
|
||||
|
|
@ -63,9 +63,9 @@ func (c *OutputCommand) Outputs(statePath string) (map[string]*states.OutputValu
|
|||
}
|
||||
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(nil)
|
||||
b, backendDiags := c.backend(".", view)
|
||||
diags = diags.Append(backendDiags)
|
||||
if diags.HasErrors() {
|
||||
if backendDiags.HasErrors() {
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -124,18 +124,9 @@ func (c *PlanCommand) PrepareBackend(args *arguments.State, viewType arguments.V
|
|||
// difficult but would make their use easier to understand.
|
||||
c.Meta.applyStateArguments(args)
|
||||
|
||||
backendConfig, diags := c.loadBackendConfig(".")
|
||||
if diags.HasErrors() {
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
// Load the backend
|
||||
be, beDiags := c.Backend(&BackendOpts{
|
||||
BackendConfig: backendConfig,
|
||||
ViewType: viewType,
|
||||
})
|
||||
diags = diags.Append(beDiags)
|
||||
if beDiags.HasErrors() {
|
||||
be, diags := c.backend(".", viewType)
|
||||
if diags.HasErrors() {
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import (
|
|||
|
||||
"github.com/xlab/treeprint"
|
||||
|
||||
"github.com/hashicorp/terraform/internal/command/arguments"
|
||||
"github.com/hashicorp/terraform/internal/configs"
|
||||
"github.com/hashicorp/terraform/internal/getproviders"
|
||||
"github.com/hashicorp/terraform/internal/tfdiags"
|
||||
|
|
@ -81,9 +82,7 @@ func (c *ProvidersCommand) Run(args []string) int {
|
|||
}
|
||||
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(&BackendOpts{
|
||||
BackendConfig: config.Module.Backend,
|
||||
})
|
||||
b, backendDiags := c.backend(".", arguments.ViewHuman)
|
||||
diags = diags.Append(backendDiags)
|
||||
if backendDiags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ func (c *ProvidersSchemaCommand) Run(args []string) int {
|
|||
cmdFlags.Usage()
|
||||
return 1
|
||||
}
|
||||
viewType := arguments.ViewJSON // See above; enforced use of JSON output
|
||||
|
||||
// Check for user-supplied plugin path
|
||||
var err error
|
||||
|
|
@ -56,7 +57,7 @@ func (c *ProvidersSchemaCommand) Run(args []string) int {
|
|||
var diags tfdiags.Diagnostics
|
||||
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(nil)
|
||||
b, backendDiags := c.backend(".", viewType)
|
||||
diags = diags.Append(backendDiags)
|
||||
if backendDiags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
|
|
|
|||
|
|
@ -154,21 +154,8 @@ func (c *QueryCommand) Run(rawArgs []string) int {
|
|||
}
|
||||
|
||||
func (c *QueryCommand) PrepareBackend(args *arguments.State, viewType arguments.ViewType) (backendrun.OperationsBackend, tfdiags.Diagnostics) {
|
||||
backendConfig, diags := c.loadBackendConfig(".")
|
||||
if diags.HasErrors() {
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
// Load the backend
|
||||
be, beDiags := c.Backend(&BackendOpts{
|
||||
BackendConfig: backendConfig,
|
||||
ViewType: viewType,
|
||||
})
|
||||
diags = diags.Append(beDiags)
|
||||
if beDiags.HasErrors() {
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
be, diags := c.backend(".", viewType)
|
||||
return be, diags
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -117,18 +117,9 @@ func (c *RefreshCommand) PrepareBackend(args *arguments.State, viewType argument
|
|||
// difficult but would make their use easier to understand.
|
||||
c.Meta.applyStateArguments(args)
|
||||
|
||||
backendConfig, diags := c.loadBackendConfig(".")
|
||||
if diags.HasErrors() {
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
// Load the backend
|
||||
be, beDiags := c.Backend(&BackendOpts{
|
||||
BackendConfig: backendConfig,
|
||||
ViewType: viewType,
|
||||
})
|
||||
diags = diags.Append(beDiags)
|
||||
if beDiags.HasErrors() {
|
||||
be, diags := c.backend(".", viewType)
|
||||
if diags.HasErrors() {
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ func (c *ShowCommand) showFromLatestStateSnapshot() (*statefile.File, tfdiags.Di
|
|||
var diags tfdiags.Diagnostics
|
||||
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(nil)
|
||||
b, backendDiags := c.backend(".", c.viewType)
|
||||
diags = diags.Append(backendDiags)
|
||||
if backendDiags.HasErrors() {
|
||||
return nil, diags
|
||||
|
|
@ -278,9 +278,9 @@ func (c *ShowCommand) getPlanFromPath(path string) (*plans.Plan, *cloudplan.Remo
|
|||
|
||||
func (c *ShowCommand) getDataFromCloudPlan(plan *cloudplan.SavedPlanBookmark, redacted bool) (*cloudplan.RemotePlanJSON, error) {
|
||||
// Set up the backend
|
||||
b, backendDiags := c.Backend(nil)
|
||||
if backendDiags.HasErrors() {
|
||||
return nil, errUnusable(backendDiags.Err(), "cloud plan")
|
||||
b, diags := c.backend(".", c.viewType)
|
||||
if diags.HasErrors() {
|
||||
return nil, errUnusable(diags.Err(), "cloud plan")
|
||||
}
|
||||
// Cloud plans only work if we're cloud.
|
||||
cl, ok := b.(*cloud.Cloud)
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ import (
|
|||
|
||||
"github.com/hashicorp/cli"
|
||||
"github.com/hashicorp/terraform/internal/addrs"
|
||||
"github.com/hashicorp/terraform/internal/command/arguments"
|
||||
"github.com/hashicorp/terraform/internal/states"
|
||||
"github.com/hashicorp/terraform/internal/tfdiags"
|
||||
)
|
||||
|
||||
// StateIdentitiesCommand is a Command implementation that lists the resource identities
|
||||
|
|
@ -41,15 +41,16 @@ func (c *StateIdentitiesCommand) Run(args []string) int {
|
|||
cmdFlags.Usage()
|
||||
return 1
|
||||
}
|
||||
view := arguments.ViewJSON // See above
|
||||
|
||||
if statePath != "" {
|
||||
c.Meta.statePath = statePath
|
||||
}
|
||||
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(nil)
|
||||
if backendDiags.HasErrors() {
|
||||
c.showDiagnostics(backendDiags)
|
||||
b, diags := c.backend(".", view)
|
||||
if diags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
return 1
|
||||
}
|
||||
|
||||
|
|
@ -79,7 +80,6 @@ func (c *StateIdentitiesCommand) Run(args []string) int {
|
|||
}
|
||||
|
||||
var addrs []addrs.AbsResourceInstance
|
||||
var diags tfdiags.Diagnostics
|
||||
if len(args) == 0 {
|
||||
addrs, diags = c.lookupAllResourceInstanceAddrs(state)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ import (
|
|||
|
||||
"github.com/hashicorp/cli"
|
||||
"github.com/hashicorp/terraform/internal/addrs"
|
||||
"github.com/hashicorp/terraform/internal/command/arguments"
|
||||
"github.com/hashicorp/terraform/internal/states"
|
||||
"github.com/hashicorp/terraform/internal/tfdiags"
|
||||
)
|
||||
|
||||
// StateListCommand is a Command implementation that lists the resources
|
||||
|
|
@ -37,9 +37,9 @@ func (c *StateListCommand) Run(args []string) int {
|
|||
}
|
||||
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(nil)
|
||||
if backendDiags.HasErrors() {
|
||||
c.showDiagnostics(backendDiags)
|
||||
b, diags := c.backend(".", arguments.ViewHuman)
|
||||
if diags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
return 1
|
||||
}
|
||||
|
||||
|
|
@ -69,7 +69,6 @@ func (c *StateListCommand) Run(args []string) int {
|
|||
}
|
||||
|
||||
var addrs []addrs.AbsResourceInstance
|
||||
var diags tfdiags.Diagnostics
|
||||
if len(args) == 0 {
|
||||
addrs, diags = c.lookupAllResourceInstanceAddrs(state)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform/internal/addrs"
|
||||
"github.com/hashicorp/terraform/internal/command/arguments"
|
||||
"github.com/hashicorp/terraform/internal/states"
|
||||
"github.com/hashicorp/terraform/internal/states/statemgr"
|
||||
"github.com/hashicorp/terraform/internal/tfdiags"
|
||||
|
|
@ -25,7 +26,7 @@ type StateMeta struct {
|
|||
// the backend, but changes the way that backups are done. This configures
|
||||
// backups to be timestamped rather than just the original state path plus a
|
||||
// backup path.
|
||||
func (c *StateMeta) State() (statemgr.Full, error) {
|
||||
func (c *StateMeta) State(view arguments.ViewType) (statemgr.Full, error) {
|
||||
var realState statemgr.Full
|
||||
backupPath := c.backupPath
|
||||
stateOutPath := c.statePath
|
||||
|
|
@ -34,10 +35,11 @@ func (c *StateMeta) State() (statemgr.Full, error) {
|
|||
if c.statePath != "" {
|
||||
realState = statemgr.NewFilesystem(c.statePath)
|
||||
} else {
|
||||
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(nil)
|
||||
if backendDiags.HasErrors() {
|
||||
return nil, backendDiags.Err()
|
||||
b, diags := c.backend(".", view)
|
||||
if diags.HasErrors() {
|
||||
return nil, diags.Err()
|
||||
}
|
||||
|
||||
workspace, err := c.Workspace()
|
||||
|
|
|
|||
|
|
@ -92,7 +92,8 @@ func (c *StateMvCommand) Run(args []string) int {
|
|||
}
|
||||
|
||||
// Read the from state
|
||||
stateFromMgr, err := c.State()
|
||||
view := arguments.ViewHuman
|
||||
stateFromMgr, err := c.State(view)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf(errStateLoadingState, err))
|
||||
return 1
|
||||
|
|
@ -130,7 +131,7 @@ func (c *StateMvCommand) Run(args []string) int {
|
|||
c.statePath = statePathOut
|
||||
c.backupPath = backupPathOut
|
||||
|
||||
stateToMgr, err = c.State()
|
||||
stateToMgr, err = c.State(view)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf(errStateLoadingState, err))
|
||||
return 1
|
||||
|
|
@ -391,7 +392,8 @@ func (c *StateMvCommand) Run(args []string) int {
|
|||
return 0 // This is as far as we go in dry-run mode
|
||||
}
|
||||
|
||||
b, backendDiags := c.Backend(nil)
|
||||
// Load the backend
|
||||
b, backendDiags := c.backend(".", view)
|
||||
diags = diags.Append(backendDiags)
|
||||
if backendDiags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform/internal/command/arguments"
|
||||
"github.com/hashicorp/terraform/internal/states/statefile"
|
||||
"github.com/hashicorp/terraform/internal/states/statemgr"
|
||||
)
|
||||
|
|
@ -33,9 +34,10 @@ func (c *StatePullCommand) Run(args []string) int {
|
|||
}
|
||||
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(nil)
|
||||
if backendDiags.HasErrors() {
|
||||
c.showDiagnostics(backendDiags)
|
||||
view := arguments.ViewHuman
|
||||
b, diags := c.backend(".", view)
|
||||
if diags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
return 1
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ import (
|
|||
"github.com/hashicorp/terraform/internal/states/statefile"
|
||||
"github.com/hashicorp/terraform/internal/states/statemgr"
|
||||
"github.com/hashicorp/terraform/internal/terraform"
|
||||
"github.com/hashicorp/terraform/internal/tfdiags"
|
||||
)
|
||||
|
||||
// StatePushCommand is a Command implementation that allows
|
||||
|
|
@ -77,9 +76,10 @@ func (c *StatePushCommand) Run(args []string) int {
|
|||
}
|
||||
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(nil)
|
||||
if backendDiags.HasErrors() {
|
||||
c.showDiagnostics(backendDiags)
|
||||
view := arguments.ViewHuman
|
||||
b, diags := c.backend(".", view)
|
||||
if diags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
return 1
|
||||
}
|
||||
|
||||
|
|
@ -135,7 +135,6 @@ func (c *StatePushCommand) Run(args []string) int {
|
|||
|
||||
// Get schemas, if possible, before writing state
|
||||
var schemas *terraform.Schemas
|
||||
var diags tfdiags.Diagnostics
|
||||
if isCloudMode(b) {
|
||||
schemas, diags = c.MaybeGetSchemas(srcStateFile.State, nil)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,7 +76,8 @@ func (c *StateReplaceProviderCommand) Run(args []string) int {
|
|||
}
|
||||
|
||||
// Initialize the state manager as configured
|
||||
stateMgr, err := c.State()
|
||||
view := arguments.ViewHuman
|
||||
stateMgr, err := c.State(view)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf(errStateLoadingState, err))
|
||||
return 1
|
||||
|
|
@ -164,7 +165,8 @@ func (c *StateReplaceProviderCommand) Run(args []string) int {
|
|||
resource.ProviderConfig.Provider = to
|
||||
}
|
||||
|
||||
b, backendDiags := c.Backend(nil)
|
||||
// Load the backend
|
||||
b, backendDiags := c.backend(".", view)
|
||||
diags = diags.Append(backendDiags)
|
||||
if backendDiags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
|
|
|
|||
|
|
@ -48,7 +48,8 @@ func (c *StateRmCommand) Run(args []string) int {
|
|||
}
|
||||
|
||||
// Get the state
|
||||
stateMgr, err := c.State()
|
||||
view := arguments.ViewHuman
|
||||
stateMgr, err := c.State(view)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf(errStateLoadingState, err))
|
||||
return 1
|
||||
|
|
@ -115,7 +116,8 @@ func (c *StateRmCommand) Run(args []string) int {
|
|||
return 0 // This is as far as we go in dry-run mode
|
||||
}
|
||||
|
||||
b, backendDiags := c.Backend(nil)
|
||||
// Load the backend
|
||||
b, backendDiags := c.backend(".", view)
|
||||
diags = diags.Append(backendDiags)
|
||||
if backendDiags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
|
|
|
|||
|
|
@ -48,9 +48,10 @@ func (c *StateShowCommand) Run(args []string) int {
|
|||
}
|
||||
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(nil)
|
||||
if backendDiags.HasErrors() {
|
||||
c.showDiagnostics(backendDiags)
|
||||
view := arguments.ViewHuman
|
||||
b, diags := c.backend(".", view)
|
||||
if diags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
return 1
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import (
|
|||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/terraform/internal/command/arguments"
|
||||
"github.com/hashicorp/terraform/internal/states/statemgr"
|
||||
)
|
||||
|
||||
|
|
@ -31,7 +32,8 @@ func TestStateDefaultBackupExtension(t *testing.T) {
|
|||
tmp := t.TempDir()
|
||||
t.Chdir(tmp)
|
||||
|
||||
s, err := (&StateMeta{}).State()
|
||||
view := arguments.ViewHuman
|
||||
s, err := (&StateMeta{}).State(view)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,8 @@ func (c *TaintCommand) Run(args []string) int {
|
|||
}
|
||||
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(nil)
|
||||
view := arguments.ViewHuman
|
||||
b, backendDiags := c.backend(".", view)
|
||||
diags = diags.Append(backendDiags)
|
||||
if backendDiags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
terraform {
|
||||
required_providers {
|
||||
test = {
|
||||
source = "hashicorp/test"
|
||||
source = "hashicorp/test"
|
||||
version = "1.2.3"
|
||||
}
|
||||
}
|
||||
state_store "test_store" {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform/internal/command/arguments"
|
||||
"github.com/hashicorp/terraform/internal/states/statemgr"
|
||||
|
||||
"github.com/hashicorp/cli"
|
||||
|
|
@ -51,17 +52,9 @@ func (c *UnlockCommand) Run(args []string) int {
|
|||
|
||||
var diags tfdiags.Diagnostics
|
||||
|
||||
backendConfig, backendDiags := c.loadBackendConfig(configPath)
|
||||
diags = diags.Append(backendDiags)
|
||||
if diags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
return 1
|
||||
}
|
||||
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(&BackendOpts{
|
||||
BackendConfig: backendConfig,
|
||||
})
|
||||
view := arguments.ViewHuman
|
||||
b, backendDiags := c.backend(configPath, view)
|
||||
diags = diags.Append(backendDiags)
|
||||
if backendDiags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
|
|
|
|||
|
|
@ -56,7 +56,8 @@ func (c *UntaintCommand) Run(args []string) int {
|
|||
}
|
||||
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(nil)
|
||||
view := arguments.ViewHuman
|
||||
b, backendDiags := c.backend(".", view)
|
||||
diags = diags.Append(backendDiags)
|
||||
if backendDiags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
|
|
|
|||
|
|
@ -59,17 +59,9 @@ func (c *WorkspaceDeleteCommand) Run(args []string) int {
|
|||
|
||||
var diags tfdiags.Diagnostics
|
||||
|
||||
backendConfig, backendDiags := c.loadBackendConfig(configPath)
|
||||
diags = diags.Append(backendDiags)
|
||||
if diags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
return 1
|
||||
}
|
||||
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(&BackendOpts{
|
||||
BackendConfig: backendConfig,
|
||||
})
|
||||
view := arguments.ViewHuman
|
||||
b, backendDiags := c.backend(configPath, view)
|
||||
diags = diags.Append(backendDiags)
|
||||
if backendDiags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform/internal/tfdiags"
|
||||
"github.com/hashicorp/terraform/internal/command/arguments"
|
||||
"github.com/posener/complete"
|
||||
)
|
||||
|
||||
|
|
@ -35,21 +35,10 @@ func (c *WorkspaceListCommand) Run(args []string) int {
|
|||
return 1
|
||||
}
|
||||
|
||||
var diags tfdiags.Diagnostics
|
||||
|
||||
backendConfig, backendDiags := c.loadBackendConfig(configPath)
|
||||
diags = diags.Append(backendDiags)
|
||||
if diags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
return 1
|
||||
}
|
||||
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(&BackendOpts{
|
||||
BackendConfig: backendConfig,
|
||||
})
|
||||
diags = diags.Append(backendDiags)
|
||||
if backendDiags.HasErrors() {
|
||||
view := arguments.ViewHuman
|
||||
b, diags := c.backend(configPath, view)
|
||||
if diags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
return 1
|
||||
}
|
||||
|
|
@ -58,6 +47,7 @@ func (c *WorkspaceListCommand) Run(args []string) int {
|
|||
c.ignoreRemoteVersionConflict(b)
|
||||
|
||||
states, wDiags := b.Workspaces()
|
||||
diags = diags.Append(wDiags)
|
||||
if wDiags.HasErrors() {
|
||||
c.Ui.Error(wDiags.Err().Error())
|
||||
return 1
|
||||
|
|
|
|||
|
|
@ -68,19 +68,10 @@ func (c *WorkspaceNewCommand) Run(args []string) int {
|
|||
|
||||
var diags tfdiags.Diagnostics
|
||||
|
||||
backendConfig, backendDiags := c.loadBackendConfig(configPath)
|
||||
diags = diags.Append(backendDiags)
|
||||
if diags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
return 1
|
||||
}
|
||||
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(&BackendOpts{
|
||||
BackendConfig: backendConfig,
|
||||
})
|
||||
diags = diags.Append(backendDiags)
|
||||
if backendDiags.HasErrors() {
|
||||
view := arguments.ViewHuman
|
||||
b, diags := c.backend(configPath, view)
|
||||
if diags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
return 1
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/hashicorp/cli"
|
||||
"github.com/hashicorp/terraform/internal/tfdiags"
|
||||
"github.com/hashicorp/terraform/internal/command/arguments"
|
||||
"github.com/posener/complete"
|
||||
)
|
||||
|
||||
|
|
@ -42,15 +42,6 @@ func (c *WorkspaceSelectCommand) Run(args []string) int {
|
|||
return 1
|
||||
}
|
||||
|
||||
var diags tfdiags.Diagnostics
|
||||
|
||||
backendConfig, backendDiags := c.loadBackendConfig(configPath)
|
||||
diags = diags.Append(backendDiags)
|
||||
if diags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
return 1
|
||||
}
|
||||
|
||||
current, isOverridden := c.WorkspaceOverridden()
|
||||
if isOverridden {
|
||||
c.Ui.Error(envIsOverriddenSelectError)
|
||||
|
|
@ -58,11 +49,9 @@ func (c *WorkspaceSelectCommand) Run(args []string) int {
|
|||
}
|
||||
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(&BackendOpts{
|
||||
BackendConfig: backendConfig,
|
||||
})
|
||||
diags = diags.Append(backendDiags)
|
||||
if backendDiags.HasErrors() {
|
||||
view := arguments.ViewHuman
|
||||
b, diags := c.backend(configPath, view)
|
||||
if diags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
return 1
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue