Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix addr and ID usage for import #24

Merged
merged 3 commits into from
Jul 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions tfexec/apply_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ func TestApply(t *testing.T) {
td := testTempDir(t)
defer os.RemoveAll(td)

tf, err := NewTerraform(td, tfPath)
tf, err := NewTerraform(td, tfVersion(t, "0.12.28"))
if err != nil {
t.Fatal(err)
}

err = copyFile(filepath.Join(testFixtureDir, testConfigFileName), filepath.Join(td, testConfigFileName))
err = copyFile(filepath.Join(testFixtureDir, "basic/main.tf"), td)
if err != nil {
t.Fatalf("error copying config file into test dir: %s", err)
}
Expand All @@ -37,7 +37,7 @@ func TestApplyCmd(t *testing.T) {
td := testTempDir(t)
defer os.RemoveAll(td)

tf, err := NewTerraform(td, tfPath)
tf, err := NewTerraform(td, tfVersion(t, "0.12.28"))
if err != nil {
t.Fatal(err)
}
Expand Down
2 changes: 1 addition & 1 deletion tfexec/destroy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ func TestDestroyCmd(t *testing.T) {
td := testTempDir(t)
defer os.RemoveAll(td)

tf, err := NewTerraform(td, tfPath)
tf, err := NewTerraform(td, tfVersion(t, "0.12.28"))
if err != nil {
t.Fatal(err)
}
Expand Down
17 changes: 6 additions & 11 deletions tfexec/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,6 @@ type ImportOption interface {
configureImport(*importConfig)
}

func (opt *AddrOption) configureImport(conf *importConfig) {
conf.addr = opt.addr
}

func (opt *IdOption) configureImport(conf *importConfig) {
conf.id = opt.id
}

func (opt *BackupOption) configureImport(conf *importConfig) {
conf.backup = opt.path
}
Expand Down Expand Up @@ -75,8 +67,8 @@ func (opt *VarFileOption) configureImport(conf *importConfig) {
conf.varFile = opt.path
}

func (t *Terraform) Import(ctx context.Context, opts ...ImportOption) error {
importCmd := t.ImportCmd(ctx, opts...)
func (t *Terraform) Import(ctx context.Context, address, id string, opts ...ImportOption) error {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have these as explicit strings here instead of the options model since they are required for this command.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is reasonable, but it means a breaking change for tfexec if terraform import gains or loses required arguments during future terraform versions.

To my knowledge there is no other terraform subcommand with required arguments, but I may be wrong...

importCmd := t.ImportCmd(ctx, address, id, opts...)

var errBuf strings.Builder
importCmd.Stderr = &errBuf
Expand All @@ -89,7 +81,7 @@ func (t *Terraform) Import(ctx context.Context, opts ...ImportOption) error {
return nil
}

func (tf *Terraform) ImportCmd(ctx context.Context, opts ...ImportOption) *exec.Cmd {
func (tf *Terraform) ImportCmd(ctx context.Context, address, id string, opts ...ImportOption) *exec.Cmd {
c := defaultImportOptions

for _, o := range opts {
Expand Down Expand Up @@ -133,5 +125,8 @@ func (tf *Terraform) ImportCmd(ctx context.Context, opts ...ImportOption) *exec.
}
}

// required args, always pass
args = append(args, address, id)

return tf.buildTerraformCmd(ctx, args...)
}
82 changes: 76 additions & 6 deletions tfexec/import_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,101 @@ package tfexec
import (
"context"
"os"
"path/filepath"
"strings"
"testing"
)

func TestImport(t *testing.T) {
const (
expectedID = "asdlfjksdlfkjsdlfk"
resourceAddress = "random_string.random_string"
)
ctx := context.Background()

for _, tfv := range []string{
// "0.11.14", doesn't support show JSON output, but does support import
"0.12.28",
"0.13.0-beta3",
} {
t.Run(tfv, func(t *testing.T) {
td := testTempDir(t)
defer os.RemoveAll(td)

err := copyFiles(filepath.Join(testFixtureDir, "import"), td)
if err != nil {
t.Fatal(err)
}

tf, err := NewTerraform(td, tfVersion(t, tfv))
if err != nil {
t.Fatal(err)
}

err = tf.Init(ctx, Lock(false))
if err != nil {
t.Fatal(err)
}

err = tf.Import(ctx, resourceAddress, expectedID, DisableBackup(), Lock(false))
if err != nil {
t.Fatal(err)
}

state, err := tf.StateShow(ctx)
if err != nil {
t.Fatal(err)
}

for _, r := range state.Values.RootModule.Resources {
if r.Address != resourceAddress {
continue
}

raw, ok := r.AttributeValues["id"]
if !ok {
t.Fatal("value not found for \"id\" attribute")
}
actual, ok := raw.(string)
if !ok {
t.Fatalf("unable to cast %T to string: %#v", raw, raw)
}

if actual != expectedID {
t.Fatalf("expected %q, got %q", expectedID, actual)
}

// success
return
}

t.Fatalf("imported resource %q not found", resourceAddress)
})
}
}

func TestImportCmd(t *testing.T) {
td := testTempDir(t)
defer os.RemoveAll(td)

tf, err := NewTerraform(td, tfPath)
tf, err := NewTerraform(td, tfVersion(t, "0.12.28"))
if err != nil {
t.Fatal(err)
}

// defaults
importCmd := tf.ImportCmd(context.Background())
importCmd := tf.ImportCmd(context.Background(), "my-addr", "my-id")

actual := strings.TrimPrefix(cmdString(importCmd), importCmd.Path+" ")

expected := "import -no-color -input=false -lock-timeout=0s -lock=true"
expected := "import -no-color -input=false -lock-timeout=0s -lock=true my-addr my-id"

if actual != expected {
t.Fatalf("expected default arguments of ImportCmd:\n%s\n actual arguments:\n%s\n", expected, actual)
}

// override all defaults
importCmd = tf.ImportCmd(context.Background(),
importCmd = tf.ImportCmd(context.Background(), "my-addr2", "my-id2",
Backup("testbackup"),
LockTimeout("200s"),
State("teststate"),
Expand All @@ -37,11 +106,12 @@ func TestImportCmd(t *testing.T) {
Lock(false),
Var("var1=foo"),
Var("var2=bar"),
AllowMissingConfig(true))
AllowMissingConfig(true),
)

actual = strings.TrimPrefix(cmdString(importCmd), importCmd.Path+" ")

expected = "import -no-color -input=false -backup=testbackup -lock-timeout=200s -state=teststate -state-out=teststateout -var-file=testvarfile -lock=false -allow-missing-config -var 'var1=foo' -var 'var2=bar'"
expected = "import -no-color -input=false -backup=testbackup -lock-timeout=200s -state=teststate -state-out=teststateout -var-file=testvarfile -lock=false -allow-missing-config -var 'var1=foo' -var 'var2=bar' my-addr2 my-id2"

if actual != expected {
t.Fatalf("expected arguments of ImportCmd:\n%s\n actual arguments:\n%s\n", expected, actual)
Expand Down
2 changes: 1 addition & 1 deletion tfexec/init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ func TestInitCmd(t *testing.T) {
td := testTempDir(t)
defer os.RemoveAll(td)

tf, err := NewTerraform(td, tfPath)
tf, err := NewTerraform(td, tfVersion(t, "0.12.28"))
if err != nil {
t.Fatal(err)
}
Expand Down
21 changes: 5 additions & 16 deletions tfexec/options.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,5 @@
package tfexec

type AddrOption struct {
addr string
}

func Addr(addr string) *AddrOption {
return &AddrOption{addr}
}

type AllowMissingConfigOption struct {
allowMissingConfig bool
}
Expand Down Expand Up @@ -40,6 +32,11 @@ func Backup(path string) *BackupOption {
return &BackupOption{path}
}

// DisableBackup is a convenience method for Backup("-"), indicating backup state should be disabled.
func DisableBackup() *BackupOption {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happy with this direction - we can provide more convenience options as use cases become clear.

return &BackupOption{"-"}
}

type ConfigOption struct {
path string
}
Expand Down Expand Up @@ -97,14 +94,6 @@ func GetPlugins(getPlugins bool) *GetPluginsOption {
return &GetPluginsOption{getPlugins}
}

type IdOption struct {
id string
}

func Id(id string) *IdOption {
return &IdOption{id}
}

type LockOption struct {
lock bool
}
Expand Down
2 changes: 1 addition & 1 deletion tfexec/output_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ func TestOutputCmd(t *testing.T) {
td := testTempDir(t)
defer os.RemoveAll(td)

tf, err := NewTerraform(td, tfPath)
tf, err := NewTerraform(td, tfVersion(t, "0.12.28"))
if err != nil {
t.Fatal(err)
}
Expand Down
2 changes: 1 addition & 1 deletion tfexec/plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ func TestPlanCmd(t *testing.T) {
td := testTempDir(t)
defer os.RemoveAll(td)

tf, err := NewTerraform(td, tfPath)
tf, err := NewTerraform(td, tfVersion(t, "0.12.28"))
if err != nil {
t.Fatal(err)
}
Expand Down
2 changes: 1 addition & 1 deletion tfexec/providers_schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ func TestProvidersSchemaCmd(t *testing.T) {
td := testTempDir(t)
defer os.RemoveAll(td)

tf, err := NewTerraform(td, tfPath)
tf, err := NewTerraform(td, tfVersion(t, "0.12.28"))
if err != nil {
t.Fatal(err)
}
Expand Down
16 changes: 6 additions & 10 deletions tfexec/show_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,15 @@ func TestStateShow(t *testing.T) {
td := testTempDir(t)
defer os.RemoveAll(td)

tf, err := NewTerraform(td, tfPath)
tf, err := NewTerraform(td, tfVersion(t, "0.12.28"))
if err != nil {
t.Fatal(err)
}

// copy state and config files into test dir
err = copyFile(filepath.Join(testFixtureDir, testTerraformStateFileName), filepath.Join(td, testTerraformStateFileName))
err = copyFiles(filepath.Join(testFixtureDir, "basic"), td)
if err != nil {
t.Fatalf("error copying state file into test dir: %s", err)
}
err = copyFile(filepath.Join(testFixtureDir, testConfigFileName), filepath.Join(td, testConfigFileName))
if err != nil {
t.Fatalf("error copying config file into test dir: %s", err)
t.Fatalf("error copying files into test dir: %s", err)
}

expected := tfjson.State{
Expand Down Expand Up @@ -70,12 +66,12 @@ func TestShow_errInitRequired(t *testing.T) {
td := testTempDir(t)
defer os.RemoveAll(td)

tf, err := NewTerraform(td, tfPath)
tf, err := NewTerraform(td, tfVersion(t, "0.12.28"))
if err != nil {
t.Fatal(err)
}

err = copyFile(filepath.Join(testFixtureDir, testTerraformStateFileName), filepath.Join(td, testTerraformStateFileName))
err = copyFile(filepath.Join(testFixtureDir, "basic", testTerraformStateFileName), td)

_, err = tf.StateShow(context.Background())
if err == nil {
Expand All @@ -92,7 +88,7 @@ func TestStateShowCmd(t *testing.T) {
td := testTempDir(t)
defer os.RemoveAll(td)

tf, err := NewTerraform(td, tfPath)
tf, err := NewTerraform(td, tfVersion(t, "0.12.28"))
if err != nil {
t.Fatal(err)
}
Expand Down
Loading