Don't ForceLocal for the import backend
While the `local.Local` backend is the only implementation of `backend.Local`, creating the backend with `ForceLocal` bypasses the `backend.Backend` in the `local.Local` causing a local state to be implicitly created rather than using the configured state backend. Add a test that imports into a configured backend (using the "local" backend as a remote state proxy). This further confirms the confusing nature of ForceLocal, as the backend _is_ local, but not from the viewpoint of meta.Backend.
This commit is contained in:
parent
8b3b678c2f
commit
e3748901b4
|
@ -123,15 +123,18 @@ func (c *ImportCommand) Run(args []string) int {
|
|||
|
||||
// Load the backend
|
||||
b, err := c.Backend(&BackendOpts{
|
||||
Config: mod.Config(),
|
||||
ForceLocal: true,
|
||||
Config: mod.Config(),
|
||||
})
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Failed to load backend: %s", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
// We require a local backend
|
||||
// We require a backend.Local to build a context.
|
||||
// This isn't necessarily a "local.Local" backend, which provides local
|
||||
// operations, however that is the only current implementation. A
|
||||
// "local.Local" backend also doesn't necessarily provide local state, as
|
||||
// that may be delegated to a "remotestate.Backend".
|
||||
local, ok := b.(backend.Local)
|
||||
if !ok {
|
||||
c.Ui.Error(ErrUnsupportedLocalOp)
|
||||
|
|
|
@ -110,6 +110,88 @@ func TestImport_providerConfig(t *testing.T) {
|
|||
testStateOutput(t, statePath, testImportStr)
|
||||
}
|
||||
|
||||
// "remote" state provided by the "local" backend
|
||||
func TestImport_remoteState(t *testing.T) {
|
||||
td := tempDir(t)
|
||||
copy.CopyDir(testFixturePath("import-provider-remote-state"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
statePath := "imported.tfstate"
|
||||
|
||||
// init our backend
|
||||
ui := new(cli.MockUi)
|
||||
m := Meta{
|
||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||
Ui: ui,
|
||||
}
|
||||
|
||||
ic := &InitCommand{
|
||||
Meta: m,
|
||||
providerInstaller: &mockProviderInstaller{
|
||||
Providers: map[string][]string{
|
||||
"test": []string{"1.2.3"},
|
||||
},
|
||||
|
||||
Dir: m.pluginDir(),
|
||||
},
|
||||
}
|
||||
|
||||
if code := ic.Run([]string{}); code != 0 {
|
||||
t.Fatalf("bad: \n%s", ui.ErrorWriter)
|
||||
}
|
||||
|
||||
p := testProvider()
|
||||
ui = new(cli.MockUi)
|
||||
c := &ImportCommand{
|
||||
Meta: Meta{
|
||||
testingOverrides: metaOverridesForProvider(p),
|
||||
Ui: ui,
|
||||
},
|
||||
}
|
||||
|
||||
p.ImportStateFn = nil
|
||||
p.ImportStateReturn = []*terraform.InstanceState{
|
||||
&terraform.InstanceState{
|
||||
ID: "yay",
|
||||
Ephemeral: terraform.EphemeralState{
|
||||
Type: "test_instance",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
configured := false
|
||||
p.ConfigureFn = func(c *terraform.ResourceConfig) error {
|
||||
configured = true
|
||||
|
||||
if v, ok := c.Get("foo"); !ok || v.(string) != "bar" {
|
||||
return fmt.Errorf("bad value: %#v", v)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
args := []string{
|
||||
"test_instance.foo",
|
||||
"bar",
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
fmt.Println(ui.OutputWriter)
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
}
|
||||
|
||||
// Verify that we were called
|
||||
if !configured {
|
||||
t.Fatal("Configure should be called")
|
||||
}
|
||||
|
||||
if !p.ImportStateCalled {
|
||||
t.Fatal("ImportState should be called")
|
||||
}
|
||||
|
||||
testStateOutput(t, statePath, testImportStr)
|
||||
}
|
||||
|
||||
func TestImport_providerConfigWithVar(t *testing.T) {
|
||||
defer testChdir(t, testFixturePath("import-provider-var"))()
|
||||
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
terraform {
|
||||
backend "local" {
|
||||
path = "imported.tfstate"
|
||||
}
|
||||
}
|
||||
|
||||
provider "test" {
|
||||
foo = "bar"
|
||||
}
|
||||
|
||||
resource "test_instance" "foo" {
|
||||
}
|
Loading…
Reference in New Issue