diff --git a/command/import.go b/command/import.go index 015610da5..cc9792872 100644 --- a/command/import.go +++ b/command/import.go @@ -3,6 +3,7 @@ package command import ( "fmt" "log" + "os" "strings" "github.com/hashicorp/terraform/terraform" @@ -34,8 +35,16 @@ func (c *ImportCommand) Run(args []string) int { 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 ctx, _, err := c.Context(contextOpts{ + Path: pwd, + PathEmptyOk: true, StatePath: c.Meta.statePath, Parallelism: c.Meta.parallelism, }) diff --git a/command/import_test.go b/command/import_test.go index 1341fa5ea..319388057 100644 --- a/command/import_test.go +++ b/command/import_test.go @@ -1,6 +1,7 @@ package command import ( + "fmt" "testing" "github.com/hashicorp/terraform/terraform" @@ -45,6 +46,62 @@ func TestImport(t *testing.T) { 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) { p := testProvider() diff --git a/command/meta.go b/command/meta.go index 4e142585d..b2416abd5 100644 --- a/command/meta.go +++ b/command/meta.go @@ -5,11 +5,14 @@ import ( "flag" "fmt" "io" + "log" "os" "path/filepath" "strconv" + "github.com/hashicorp/errwrap" "github.com/hashicorp/go-getter" + "github.com/hashicorp/terraform/config" "github.com/hashicorp/terraform/config/module" "github.com/hashicorp/terraform/helper/experiment" "github.com/hashicorp/terraform/state" @@ -163,6 +166,17 @@ func (m *Meta) Context(copts contextOpts) (*terraform.Context, bool, error) { var mod *module.Tree if 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 { 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. type contextOpts struct { // Path to the directory where the root module is. - Path string + // + // PathEmptyOk, when set, will allow paths that have no Terraform + // configurations. The result in that case will be an empty module. + Path string + PathEmptyOk bool // 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 diff --git a/command/test-fixtures/import-provider/main.tf b/command/test-fixtures/import-provider/main.tf new file mode 100644 index 000000000..dd4a7556c --- /dev/null +++ b/command/test-fixtures/import-provider/main.tf @@ -0,0 +1,3 @@ +provider "test" { + foo = "bar" +} diff --git a/config/loader.go b/config/loader.go index c9a1295fe..0bfa89c25 100644 --- a/config/loader.go +++ b/config/loader.go @@ -12,6 +12,18 @@ import ( "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. // // The document must be a complete Terraform configuration. This function will @@ -69,9 +81,7 @@ func LoadDir(root string) (*Config, error) { return nil, err } if len(files) == 0 { - return nil, fmt.Errorf( - "No Terraform configuration files found in directory: %s", - root) + return nil, &ErrNoConfigsFound{Dir: root} } // Determine the absolute path to the directory. diff --git a/config/loader_test.go b/config/loader_test.go index dfc79f623..73b09a6fe 100644 --- a/config/loader_test.go +++ b/config/loader_test.go @@ -8,6 +8,10 @@ import ( "testing" ) +func TestErrNoConfigsFound_impl(t *testing.T) { + var _ error = new(ErrNoConfigsFound) +} + func TestIsEmptyDir(t *testing.T) { val, err := IsEmptyDir(fixtureDir) if err != nil {