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

implement Refresh #53

Merged
merged 1 commit into from
Aug 17, 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
29 changes: 29 additions & 0 deletions tfexec/internal/e2etest/refresh_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package e2etest

import (
"context"
"testing"

"github.com/hashicorp/go-version"

"github.com/hashicorp/terraform-exec/tfexec"
)

func TestRefresh(t *testing.T) {
runTest(t, "basic", func(t *testing.T, tfv *version.Version, tf *tfexec.Terraform) {
err := tf.Init(context.Background())
if err != nil {
t.Fatalf("error running Init in test directory: %s", err)
}

err = tf.Apply(context.Background())
if err != nil {
t.Fatalf("error running Apply: %s", err)
}

err = tf.Refresh(context.Background())
if err != nil {
t.Fatalf("error running Refresh: %s", err)
}
})
}
8 changes: 8 additions & 0 deletions tfexec/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ func Config(path string) *ConfigOption {
return &ConfigOption{path}
}

type DirOption struct {
path string
}

func Dir(path string) *DirOption {
return &DirOption{path}
}

type DirOrPlanOption struct {
path string
}
Expand Down
117 changes: 117 additions & 0 deletions tfexec/refresh.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package tfexec

import (
"context"
"os/exec"
"strconv"
)

type refreshConfig struct {
backup string
dir string
lock bool
lockTimeout string
state string
stateOut string
targets []string
vars []string
varFile string
}

var defaultRefreshOptions = refreshConfig{
lock: true,
lockTimeout: "0s",
}

type RefreshCmdOption interface {
configureRefresh(*refreshConfig)
}

func (opt *BackupOption) configureRefresh(conf *refreshConfig) {
conf.backup = opt.path
}

func (opt *DirOption) configureRefresh(conf *refreshConfig) {
conf.dir = opt.path
}

func (opt *LockOption) configureRefresh(conf *refreshConfig) {
conf.lock = opt.lock
}

func (opt *LockTimeoutOption) configureRefresh(conf *refreshConfig) {
conf.lockTimeout = opt.timeout
}

func (opt *StateOption) configureRefresh(conf *refreshConfig) {
conf.state = opt.path
}

func (opt *StateOutOption) configureRefresh(conf *refreshConfig) {
conf.stateOut = opt.path
}

func (opt *TargetOption) configureRefresh(conf *refreshConfig) {
conf.targets = append(conf.targets, opt.target)
}

func (opt *VarOption) configureRefresh(conf *refreshConfig) {
conf.vars = append(conf.vars, opt.assignment)
}

func (opt *VarFileOption) configureRefresh(conf *refreshConfig) {
conf.varFile = opt.path
}

func (tf *Terraform) Refresh(ctx context.Context, opts ...RefreshCmdOption) error {
return tf.runTerraformCmd(tf.refreshCmd(ctx, opts...))
}

func (tf *Terraform) refreshCmd(ctx context.Context, opts ...RefreshCmdOption) *exec.Cmd {
c := defaultRefreshOptions

for _, o := range opts {
o.configureRefresh(&c)
}

args := []string{"refresh", "-no-color", "-input=false"}

// string opts: only pass if set
if c.backup != "" {
args = append(args, "-backup="+c.backup)
}
if c.lockTimeout != "" {
args = append(args, "-lock-timeout="+c.lockTimeout)
}
if c.state != "" {
args = append(args, "-state="+c.state)
}
if c.stateOut != "" {
args = append(args, "-state-out="+c.stateOut)
}
if c.varFile != "" {
args = append(args, "-var-file="+c.varFile)
}

// boolean and numerical opts: always pass
args = append(args, "-lock="+strconv.FormatBool(c.lock))

// string slice opts: split into separate args
if c.targets != nil {
for _, ta := range c.targets {
args = append(args, "-target="+ta)
}
}
if c.vars != nil {
for _, v := range c.vars {
args = append(args, "-var", v)
}
}

// optional positional argument
if c.dir != "" {
args = append(args, c.dir)
}

return tf.buildTerraformCmd(ctx, args...)
}
55 changes: 55 additions & 0 deletions tfexec/refresh_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package tfexec

import (
"context"
"os"
"testing"

"github.com/hashicorp/terraform-exec/tfexec/internal/testutil"
)

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

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

// empty env, to avoid environ mismatch in testing
tf.SetEnv(map[string]string{})

t.Run("defaults", func(t *testing.T) {
refreshCmd := tf.refreshCmd(context.Background())

assertCmd(t, []string{
"refresh",
"-no-color",
"-input=false",
"-lock-timeout=0s",
"-lock=true",
}, nil, refreshCmd)
})

t.Run("override all defaults", func(t *testing.T) {
refreshCmd := tf.refreshCmd(context.Background(), Backup("testbackup"), LockTimeout("200s"), State("teststate"), StateOut("teststateout"), VarFile("testvarfile"), Lock(false), Target("target1"), Target("target2"), Var("var1=foo"), Var("var2=bar"), Dir("refreshdir"))

assertCmd(t, []string{
"refresh",
"-no-color",
"-input=false",
"-backup=testbackup",
"-lock-timeout=200s",
"-state=teststate",
"-state-out=teststateout",
"-var-file=testvarfile",
"-lock=false",
"-target=target1",
"-target=target2",
"-var", "var1=foo",
"-var", "var2=bar",
"refreshdir",
}, nil, refreshCmd)
})
}