command/import: load configurations and allow empty config dirs
Fixes #7774 This modifies the `import` command to load configuration files from the pwd. This also augments the configuration loading section for the CLI to have a new option (default false, same as old behavior) to allow directories with no Terraform configurations. For import, we allow directories with no Terraform configurations so this option is set to true.
This commit is contained in:
parent
2b72882405
commit
5107c33119
|
@ -3,6 +3,7 @@ package command
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/terraform"
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
@ -34,8 +35,16 @@ func (c *ImportCommand) Run(args []string) int {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pwd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
c.Ui.Error(fmt.Sprintf("Error getting pwd: %s", err))
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
// Build the context based on the arguments given
|
// Build the context based on the arguments given
|
||||||
ctx, _, err := c.Context(contextOpts{
|
ctx, _, err := c.Context(contextOpts{
|
||||||
|
Path: pwd,
|
||||||
|
PathEmptyOk: true,
|
||||||
StatePath: c.Meta.statePath,
|
StatePath: c.Meta.statePath,
|
||||||
Parallelism: c.Meta.parallelism,
|
Parallelism: c.Meta.parallelism,
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/terraform"
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
@ -45,6 +46,62 @@ func TestImport(t *testing.T) {
|
||||||
testStateOutput(t, statePath, testImportStr)
|
testStateOutput(t, statePath, testImportStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestImport_providerConfig(t *testing.T) {
|
||||||
|
defer testChdir(t, testFixturePath("import-provider"))()
|
||||||
|
|
||||||
|
statePath := testTempFile(t)
|
||||||
|
|
||||||
|
p := testProvider()
|
||||||
|
ui := new(cli.MockUi)
|
||||||
|
c := &ImportCommand{
|
||||||
|
Meta: Meta{
|
||||||
|
ContextOpts: testCtxConfig(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{
|
||||||
|
"-state", statePath,
|
||||||
|
"test_instance.foo",
|
||||||
|
"bar",
|
||||||
|
}
|
||||||
|
if code := c.Run(args); code != 0 {
|
||||||
|
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 TestRefresh_badState(t *testing.T) {
|
func TestRefresh_badState(t *testing.T) {
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
|
|
|
@ -5,11 +5,14 @@ import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/hashicorp/errwrap"
|
||||||
"github.com/hashicorp/go-getter"
|
"github.com/hashicorp/go-getter"
|
||||||
|
"github.com/hashicorp/terraform/config"
|
||||||
"github.com/hashicorp/terraform/config/module"
|
"github.com/hashicorp/terraform/config/module"
|
||||||
"github.com/hashicorp/terraform/helper/experiment"
|
"github.com/hashicorp/terraform/helper/experiment"
|
||||||
"github.com/hashicorp/terraform/state"
|
"github.com/hashicorp/terraform/state"
|
||||||
|
@ -163,6 +166,17 @@ func (m *Meta) Context(copts contextOpts) (*terraform.Context, bool, error) {
|
||||||
var mod *module.Tree
|
var mod *module.Tree
|
||||||
if copts.Path != "" {
|
if copts.Path != "" {
|
||||||
mod, err = module.NewTreeModule("", copts.Path)
|
mod, err = module.NewTreeModule("", copts.Path)
|
||||||
|
|
||||||
|
// Check for the error where we have no config files but
|
||||||
|
// allow that. If that happens, clear the error.
|
||||||
|
if errwrap.ContainsType(err, new(config.ErrNoConfigsFound)) &&
|
||||||
|
copts.PathEmptyOk {
|
||||||
|
log.Printf(
|
||||||
|
"[WARN] Empty configuration dir, ignoring: %s", copts.Path)
|
||||||
|
err = nil
|
||||||
|
mod = module.NewEmptyTree()
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false, fmt.Errorf("Error loading config: %s", err)
|
return nil, false, fmt.Errorf("Error loading config: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -495,7 +509,11 @@ func (m *Meta) outputShadowError(err error, output bool) bool {
|
||||||
// contextOpts are the options used to load a context from a command.
|
// contextOpts are the options used to load a context from a command.
|
||||||
type contextOpts struct {
|
type contextOpts struct {
|
||||||
// Path to the directory where the root module is.
|
// Path to the directory where the root module is.
|
||||||
|
//
|
||||||
|
// PathEmptyOk, when set, will allow paths that have no Terraform
|
||||||
|
// configurations. The result in that case will be an empty module.
|
||||||
Path string
|
Path string
|
||||||
|
PathEmptyOk bool
|
||||||
|
|
||||||
// StatePath is the path to the state file. If this is empty, then
|
// StatePath is the path to the state file. If this is empty, then
|
||||||
// no state will be loaded. It is also okay for this to be a path to
|
// no state will be loaded. It is also okay for this to be a path to
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
provider "test" {
|
||||||
|
foo = "bar"
|
||||||
|
}
|
|
@ -12,6 +12,18 @@ import (
|
||||||
"github.com/hashicorp/hcl"
|
"github.com/hashicorp/hcl"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ErrNoConfigsFound is the error returned by LoadDir if no
|
||||||
|
// Terraform configuration files were found in the given directory.
|
||||||
|
type ErrNoConfigsFound struct {
|
||||||
|
Dir string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e ErrNoConfigsFound) Error() string {
|
||||||
|
return fmt.Sprintf(
|
||||||
|
"No Terraform configuration files found in directory: %s",
|
||||||
|
e.Dir)
|
||||||
|
}
|
||||||
|
|
||||||
// LoadJSON loads a single Terraform configuration from a given JSON document.
|
// LoadJSON loads a single Terraform configuration from a given JSON document.
|
||||||
//
|
//
|
||||||
// The document must be a complete Terraform configuration. This function will
|
// The document must be a complete Terraform configuration. This function will
|
||||||
|
@ -69,9 +81,7 @@ func LoadDir(root string) (*Config, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if len(files) == 0 {
|
if len(files) == 0 {
|
||||||
return nil, fmt.Errorf(
|
return nil, &ErrNoConfigsFound{Dir: root}
|
||||||
"No Terraform configuration files found in directory: %s",
|
|
||||||
root)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine the absolute path to the directory.
|
// Determine the absolute path to the directory.
|
||||||
|
|
|
@ -8,6 +8,10 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestErrNoConfigsFound_impl(t *testing.T) {
|
||||||
|
var _ error = new(ErrNoConfigsFound)
|
||||||
|
}
|
||||||
|
|
||||||
func TestIsEmptyDir(t *testing.T) {
|
func TestIsEmptyDir(t *testing.T) {
|
||||||
val, err := IsEmptyDir(fixtureDir)
|
val, err := IsEmptyDir(fixtureDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in New Issue