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

add ReattachOption #78

Merged
merged 2 commits into from
Sep 9, 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
36 changes: 27 additions & 9 deletions tfexec/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ type applyConfig struct {
lock bool

// LockTimeout must be a string with time unit, e.g. '10s'
lockTimeout string
parallelism int
refresh bool
state string
stateOut string
targets []string
lockTimeout string
parallelism int
reattachInfo ReattachInfo
refresh bool
state string
stateOut string
targets []string

// Vars: each var must be supplied as a single string, e.g. 'foo=bar'
vars []string
Expand Down Expand Up @@ -80,12 +81,20 @@ func (opt *DirOrPlanOption) configureApply(conf *applyConfig) {
conf.dirOrPlan = opt.path
}

func (opt *ReattachOption) configureApply(conf *applyConfig) {
conf.reattachInfo = opt.info
}

// Apply represents the terraform apply subcommand.
func (tf *Terraform) Apply(ctx context.Context, opts ...ApplyOption) error {
return tf.runTerraformCmd(tf.applyCmd(ctx, opts...))
cmd, err := tf.applyCmd(ctx, opts...)
if err != nil {
return err
}
return tf.runTerraformCmd(cmd)
}

func (tf *Terraform) applyCmd(ctx context.Context, opts ...ApplyOption) *exec.Cmd {
func (tf *Terraform) applyCmd(ctx context.Context, opts ...ApplyOption) (*exec.Cmd, error) {
c := defaultApplyOptions

for _, o := range opts {
Expand Down Expand Up @@ -133,5 +142,14 @@ func (tf *Terraform) applyCmd(ctx context.Context, opts ...ApplyOption) *exec.Cm
args = append(args, c.dirOrPlan)
}

return tf.buildTerraformCmd(ctx, args...)
mergeEnv := map[string]string{}
if c.reattachInfo != nil {
reattachStr, err := c.reattachInfo.marshalString()
if err != nil {
return nil, err
}
mergeEnv[reattachEnvVar] = reattachStr
}

return tf.buildTerraformCmd(ctx, mergeEnv, args...), nil
}
5 changes: 4 additions & 1 deletion tfexec/apply_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func TestApplyCmd(t *testing.T) {
tf.SetEnv(map[string]string{})

t.Run("basic", func(t *testing.T) {
applyCmd := tf.applyCmd(context.Background(),
applyCmd, err := tf.applyCmd(context.Background(),
Backup("testbackup"),
LockTimeout("200s"),
State("teststate"),
Expand All @@ -37,6 +37,9 @@ func TestApplyCmd(t *testing.T) {
Var("var2=bar"),
DirOrPlan("testfile"),
)
if err != nil {
t.Fatal(err)
}

assertCmd(t, []string{
"apply",
Expand Down
32 changes: 22 additions & 10 deletions tfexec/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,16 @@ import (
)

const (
checkpointDisableEnvVar = "CHECKPOINT_DISABLE"
logEnvVar = "TF_LOG"
inputEnvVar = "TF_INPUT"
automationEnvVar = "TF_IN_AUTOMATION"
logPathEnvVar = "TF_LOG_PATH"
reattachEnvVar = "TF_REATTACH_PROVIDERS"
appendUserAgentEnvVar = "TF_APPEND_USER_AGENT"
workspaceEnvVar = "TF_WORKSPACE"
checkpointDisableEnvVar = "CHECKPOINT_DISABLE"
logEnvVar = "TF_LOG"
inputEnvVar = "TF_INPUT"
automationEnvVar = "TF_IN_AUTOMATION"
logPathEnvVar = "TF_LOG_PATH"
reattachEnvVar = "TF_REATTACH_PROVIDERS"
appendUserAgentEnvVar = "TF_APPEND_USER_AGENT"
workspaceEnvVar = "TF_WORKSPACE"
disablePluginTLSEnvVar = "TF_DISABLE_PLUGIN_TLS"
skipProviderVerifyEnvVar = "TF_SKIP_PROVIDER_VERIFY"

varEnvVarPrefix = "TF_VAR_"
)
Expand All @@ -35,6 +37,8 @@ var prohibitedEnvVars = []string{
reattachEnvVar,
appendUserAgentEnvVar,
workspaceEnvVar,
disablePluginTLSEnvVar,
skipProviderVerifyEnvVar,
}

func envMap(environ []string) map[string]string {
Expand Down Expand Up @@ -110,12 +114,20 @@ func (tf *Terraform) buildEnv(mergeEnv map[string]string) []string {
// force usage of workspace methods for switching
env[workspaceEnvVar] = ""

if tf.disablePluginTLS {
env[disablePluginTLSEnvVar] = "1"
}

if tf.skipProviderVerify {
env[skipProviderVerifyEnvVar] = "1"
}

return envSlice(env)
}

func (tf *Terraform) buildTerraformCmd(ctx context.Context, args ...string) *exec.Cmd {
func (tf *Terraform) buildTerraformCmd(ctx context.Context, mergeEnv map[string]string, args ...string) *exec.Cmd {
cmd := exec.CommandContext(ctx, tf.execPath, args...)
cmd.Env = tf.buildEnv(nil)
cmd.Env = tf.buildEnv(mergeEnv)
cmd.Dir = tf.workingDir

tf.logger.Printf("[INFO] running Terraform command: %s", cmdString(cmd))
Expand Down
36 changes: 27 additions & 9 deletions tfexec/destroy.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ type destroyConfig struct {
lock bool

// LockTimeout must be a string with time unit, e.g. '10s'
lockTimeout string
parallelism int
refresh bool
state string
stateOut string
targets []string
lockTimeout string
parallelism int
reattachInfo ReattachInfo
refresh bool
state string
stateOut string
targets []string

// Vars: each var must be supplied as a single string, e.g. 'foo=bar'
vars []string
Expand Down Expand Up @@ -81,12 +82,20 @@ func (opt *VarOption) configureDestroy(conf *destroyConfig) {
conf.vars = append(conf.vars, opt.assignment)
}

func (opt *ReattachOption) configureDestroy(conf *destroyConfig) {
conf.reattachInfo = opt.info
}

// Destroy represents the terraform destroy subcommand.
func (tf *Terraform) Destroy(ctx context.Context, opts ...DestroyOption) error {
return tf.runTerraformCmd(tf.destroyCmd(ctx, opts...))
cmd, err := tf.destroyCmd(ctx, opts...)
if err != nil {
return err
}
return tf.runTerraformCmd(cmd)
}

func (tf *Terraform) destroyCmd(ctx context.Context, opts ...DestroyOption) *exec.Cmd {
func (tf *Terraform) destroyCmd(ctx context.Context, opts ...DestroyOption) (*exec.Cmd, error) {
c := defaultDestroyOptions

for _, o := range opts {
Expand Down Expand Up @@ -134,5 +143,14 @@ func (tf *Terraform) destroyCmd(ctx context.Context, opts ...DestroyOption) *exe
args = append(args, c.dir)
}

return tf.buildTerraformCmd(ctx, args...)
mergeEnv := map[string]string{}
if c.reattachInfo != nil {
reattachStr, err := c.reattachInfo.marshalString()
if err != nil {
return nil, err
}
mergeEnv[reattachEnvVar] = reattachStr
}

return tf.buildTerraformCmd(ctx, mergeEnv, args...), nil
}
10 changes: 8 additions & 2 deletions tfexec/destroy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ func TestDestroyCmd(t *testing.T) {
tf.SetEnv(map[string]string{})

t.Run("defaults", func(t *testing.T) {
destroyCmd := tf.destroyCmd(context.Background())
destroyCmd, err := tf.destroyCmd(context.Background())
if err != nil {
t.Fatal(err)
}

assertCmd(t, []string{
"destroy",
Expand All @@ -36,7 +39,10 @@ func TestDestroyCmd(t *testing.T) {
})

t.Run("override all defaults", func(t *testing.T) {
destroyCmd := tf.destroyCmd(context.Background(), Backup("testbackup"), LockTimeout("200s"), State("teststate"), StateOut("teststateout"), VarFile("testvarfile"), Lock(false), Parallelism(99), Refresh(false), Target("target1"), Target("target2"), Var("var1=foo"), Var("var2=bar"), Dir("destroydir"))
destroyCmd, err := tf.destroyCmd(context.Background(), Backup("testbackup"), LockTimeout("200s"), State("teststate"), StateOut("teststateout"), VarFile("testvarfile"), Lock(false), Parallelism(99), Refresh(false), Target("target1"), Target("target2"), Var("var1=foo"), Var("var2=bar"), Dir("destroydir"))
if err != nil {
t.Fatal(err)
}

assertCmd(t, []string{
"destroy",
Expand Down
24 changes: 21 additions & 3 deletions tfexec/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type importConfig struct {
allowMissingConfig bool
lock bool
lockTimeout string
reattachInfo ReattachInfo
state string
stateOut string
vars []string
Expand Down Expand Up @@ -51,6 +52,10 @@ func (opt *LockTimeoutOption) configureImport(conf *importConfig) {
conf.lockTimeout = opt.timeout
}

func (opt *ReattachOption) configureImport(conf *importConfig) {
conf.reattachInfo = opt.info
}

func (opt *StateOption) configureImport(conf *importConfig) {
conf.state = opt.path
}
Expand All @@ -69,10 +74,14 @@ func (opt *VarFileOption) configureImport(conf *importConfig) {

// Import represents the terraform import subcommand.
func (tf *Terraform) Import(ctx context.Context, address, id string, opts ...ImportOption) error {
return tf.runTerraformCmd(tf.importCmd(ctx, address, id, opts...))
cmd, err := tf.importCmd(ctx, address, id, opts...)
if err != nil {
return err
}
return tf.runTerraformCmd(cmd)
}

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

for _, o := range opts {
Expand Down Expand Up @@ -119,5 +128,14 @@ func (tf *Terraform) importCmd(ctx context.Context, address, id string, opts ...
// required args, always pass
args = append(args, address, id)

return tf.buildTerraformCmd(ctx, args...)
mergeEnv := map[string]string{}
if c.reattachInfo != nil {
reattachStr, err := c.reattachInfo.marshalString()
if err != nil {
return nil, err
}
mergeEnv[reattachEnvVar] = reattachStr
}

return tf.buildTerraformCmd(ctx, mergeEnv, args...), nil
}
10 changes: 8 additions & 2 deletions tfexec/import_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ func TestImportCmd(t *testing.T) {
tf.SetEnv(map[string]string{})

t.Run("defaults", func(t *testing.T) {
importCmd := tf.importCmd(context.Background(), "my-addr", "my-id")
importCmd, err := tf.importCmd(context.Background(), "my-addr", "my-id")
if err != nil {
t.Fatal(err)
}

assertCmd(t, []string{
"import",
Expand All @@ -35,7 +38,7 @@ func TestImportCmd(t *testing.T) {
})

t.Run("override all defaults", func(t *testing.T) {
importCmd := tf.importCmd(context.Background(), "my-addr2", "my-id2",
importCmd, err := tf.importCmd(context.Background(), "my-addr2", "my-id2",
Backup("testbackup"),
LockTimeout("200s"),
State("teststate"),
Expand All @@ -46,6 +49,9 @@ func TestImportCmd(t *testing.T) {
Var("var2=bar"),
AllowMissingConfig(true),
)
if err != nil {
t.Fatal(err)
}

assertCmd(t, []string{
"import",
Expand Down
24 changes: 21 additions & 3 deletions tfexec/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type initConfig struct {
lock bool
lockTimeout string
pluginDir []string
reattachInfo ReattachInfo
reconfigure bool
upgrade bool
verifyPlugins bool
Expand Down Expand Up @@ -75,6 +76,10 @@ func (opt *PluginDirOption) configureInit(conf *initConfig) {
conf.pluginDir = append(conf.pluginDir, opt.pluginDir)
}

func (opt *ReattachOption) configureInit(conf *initConfig) {
conf.reattachInfo = opt.info
}

func (opt *ReconfigureOption) configureInit(conf *initConfig) {
conf.reconfigure = opt.reconfigure
}
Expand All @@ -89,10 +94,14 @@ func (opt *VerifyPluginsOption) configureInit(conf *initConfig) {

// Init represents the terraform init subcommand.
func (tf *Terraform) Init(ctx context.Context, opts ...InitOption) error {
return tf.runTerraformCmd(tf.initCmd(ctx, opts...))
cmd, err := tf.initCmd(ctx, opts...)
if err != nil {
return err
}
return tf.runTerraformCmd(cmd)
}

func (tf *Terraform) initCmd(ctx context.Context, opts ...InitOption) *exec.Cmd {
func (tf *Terraform) initCmd(ctx context.Context, opts ...InitOption) (*exec.Cmd, error) {
c := defaultInitOptions

for _, o := range opts {
Expand Down Expand Up @@ -139,5 +148,14 @@ func (tf *Terraform) initCmd(ctx context.Context, opts ...InitOption) *exec.Cmd
args = append(args, c.dir)
}

return tf.buildTerraformCmd(ctx, args...)
mergeEnv := map[string]string{}
if c.reattachInfo != nil {
reattachStr, err := c.reattachInfo.marshalString()
if err != nil {
return nil, err
}
mergeEnv[reattachEnvVar] = reattachStr
}

return tf.buildTerraformCmd(ctx, mergeEnv, args...), nil
}
7 changes: 5 additions & 2 deletions tfexec/init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func TestInitCmd(t *testing.T) {

t.Run("defaults", func(t *testing.T) {
// defaults
initCmd := tf.initCmd(context.Background())
initCmd, err := tf.initCmd(context.Background())
if err != nil {
t.Fatal(err)
}
Expand All @@ -43,7 +43,10 @@ func TestInitCmd(t *testing.T) {
})

t.Run("override all defaults", func(t *testing.T) {
initCmd := tf.initCmd(context.Background(), Backend(false), BackendConfig("confpath1"), BackendConfig("confpath2"), FromModule("testsource"), Get(false), GetPlugins(false), Lock(false), LockTimeout("999s"), PluginDir("testdir1"), PluginDir("testdir2"), Reconfigure(true), Upgrade(true), VerifyPlugins(false), Dir("initdir"))
initCmd, err := tf.initCmd(context.Background(), Backend(false), BackendConfig("confpath1"), BackendConfig("confpath2"), FromModule("testsource"), Get(false), GetPlugins(false), Lock(false), LockTimeout("999s"), PluginDir("testdir1"), PluginDir("testdir2"), Reconfigure(true), Upgrade(true), VerifyPlugins(false), Dir("initdir"))
if err != nil {
t.Fatal(err)
}

assertCmd(t, []string{
"init",
Expand Down
Loading