Skip to content

Commit

Permalink
feat: add refresh-only flag for plan and apply methods (#402)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kurounin authored Aug 31, 2023
1 parent 2210f68 commit ec5a394
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 0 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ BUG FIXES:

- Fix bug in which the `TF_WORKSPACE` env var was set to an empty string, instead of being unset as intended. [GH-388]

ENHANCEMENTS:

- tfexec: Add `-refresh-only` to `(Terraform).Apply()` and `(Terraform).Plan()` methods ([#402](https://github.com/hashicorp/terraform-exec/pull/402))

# 0.18.1 (March 01, 2023)

BUG FIXES:
Expand Down
16 changes: 16 additions & 0 deletions tfexec/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type applyConfig struct {
parallelism int
reattachInfo ReattachInfo
refresh bool
refreshOnly bool
replaceAddrs []string
state string
stateOut string
Expand Down Expand Up @@ -80,6 +81,10 @@ func (opt *RefreshOption) configureApply(conf *applyConfig) {
conf.refresh = opt.refresh
}

func (opt *RefreshOnlyOption) configureApply(conf *applyConfig) {
conf.refreshOnly = opt.refreshOnly
}

func (opt *ReplaceOption) configureApply(conf *applyConfig) {
conf.replaceAddrs = append(conf.replaceAddrs, opt.address)
}
Expand Down Expand Up @@ -187,6 +192,17 @@ func (tf *Terraform) buildApplyArgs(ctx context.Context, c applyConfig) ([]strin
args = append(args, "-parallelism="+fmt.Sprint(c.parallelism))
args = append(args, "-refresh="+strconv.FormatBool(c.refresh))

if c.refreshOnly {
err := tf.compatible(ctx, tf0_15_4, nil)
if err != nil {
return nil, fmt.Errorf("refresh-only option was introduced in Terraform 0.15.4: %w", err)
}
if !c.refresh {
return nil, fmt.Errorf("you cannot use refresh=false in refresh-only planning mode")
}
args = append(args, "-refresh-only")
}

// string slice opts: split into separate args
if c.replaceAddrs != nil {
err := tf.compatible(ctx, tf0_15_2, nil)
Expand Down
20 changes: 20 additions & 0 deletions tfexec/apply_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,26 @@ func TestApplyCmd(t *testing.T) {
"testfile",
}, nil, applyCmd)
})

t.Run("refresh-only operation", func(t *testing.T) {
applyCmd, err := tf.applyCmd(context.Background(),
RefreshOnly(true),
)
if err != nil {
t.Fatal(err)
}

assertCmd(t, []string{
"apply",
"-no-color",
"-auto-approve",
"-input=false",
"-lock=true",
"-parallelism=10",
"-refresh=true",
"-refresh-only",
}, nil, applyCmd)
})
}

func TestApplyJSONCmd(t *testing.T) {
Expand Down
8 changes: 8 additions & 0 deletions tfexec/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,14 @@ func Refresh(refresh bool) *RefreshOption {
return &RefreshOption{refresh}
}

type RefreshOnlyOption struct {
refreshOnly bool
}

func RefreshOnly(refreshOnly bool) *RefreshOnlyOption {
return &RefreshOnlyOption{refreshOnly}
}

type ReplaceOption struct {
address string
}
Expand Down
16 changes: 16 additions & 0 deletions tfexec/plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type planConfig struct {
parallelism int
reattachInfo ReattachInfo
refresh bool
refreshOnly bool
replaceAddrs []string
state string
targets []string
Expand Down Expand Up @@ -68,6 +69,10 @@ func (opt *RefreshOption) configurePlan(conf *planConfig) {
conf.refresh = opt.refresh
}

func (opt *RefreshOnlyOption) configurePlan(conf *planConfig) {
conf.refreshOnly = opt.refreshOnly
}

func (opt *ReplaceOption) configurePlan(conf *planConfig) {
conf.replaceAddrs = append(conf.replaceAddrs, opt.address)
}
Expand Down Expand Up @@ -202,6 +207,17 @@ func (tf *Terraform) buildPlanArgs(ctx context.Context, c planConfig) ([]string,
args = append(args, "-parallelism="+fmt.Sprint(c.parallelism))
args = append(args, "-refresh="+strconv.FormatBool(c.refresh))

if c.refreshOnly {
err := tf.compatible(ctx, tf0_15_4, nil)
if err != nil {
return nil, fmt.Errorf("refresh-only option was introduced in Terraform 0.15.4: %w", err)
}
if !c.refresh {
return nil, fmt.Errorf("you cannot use refresh=false in refresh-only planning mode")
}
args = append(args, "-refresh-only")
}

// unary flags: pass if true
if c.replaceAddrs != nil {
err := tf.compatible(ctx, tf0_15_2, nil)
Expand Down
19 changes: 19 additions & 0 deletions tfexec/plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,25 @@ func TestPlanCmd(t *testing.T) {
"earth",
}, nil, planCmd)
})

t.Run("run a refresh-only plan", func(t *testing.T) {
planCmd, err := tf.planCmd(context.Background(), RefreshOnly(true))
if err != nil {
t.Fatal(err)
}

assertCmd(t, []string{
"plan",
"-no-color",
"-input=false",
"-detailed-exitcode",
"-lock-timeout=0s",
"-lock=true",
"-parallelism=10",
"-refresh=true",
"-refresh-only",
}, nil, planCmd)
})
}

func TestPlanJSONCmd(t *testing.T) {
Expand Down
1 change: 1 addition & 0 deletions tfexec/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ var (
tf0_15_0 = version.Must(version.NewVersion("0.15.0"))
tf0_15_2 = version.Must(version.NewVersion("0.15.2"))
tf0_15_3 = version.Must(version.NewVersion("0.15.3"))
tf0_15_4 = version.Must(version.NewVersion("0.15.4"))
tf1_1_0 = version.Must(version.NewVersion("1.1.0"))
tf1_4_0 = version.Must(version.NewVersion("1.4.0"))
tf1_6_0 = version.Must(version.NewVersion("1.6.0"))
Expand Down

0 comments on commit ec5a394

Please sign in to comment.