mirror of
https://github.com/thegeeklab/wp-opentofu.git
synced 2024-11-24 13:20:39 +00:00
refactor: switch to plugin Cmd and add tests (#44)
This commit is contained in:
parent
2eda2b50fc
commit
dcc53a341d
4
go.mod
4
go.mod
@ -5,6 +5,7 @@ go 1.22
|
|||||||
require (
|
require (
|
||||||
github.com/Masterminds/semver/v3 v3.2.1
|
github.com/Masterminds/semver/v3 v3.2.1
|
||||||
github.com/rs/zerolog v1.32.0
|
github.com/rs/zerolog v1.32.0
|
||||||
|
github.com/stretchr/testify v1.9.0
|
||||||
github.com/thegeeklab/wp-plugin-go/v2 v2.3.1
|
github.com/thegeeklab/wp-plugin-go/v2 v2.3.1
|
||||||
github.com/urfave/cli/v2 v2.27.2
|
github.com/urfave/cli/v2 v2.27.2
|
||||||
golang.org/x/sys v0.20.0
|
golang.org/x/sys v0.20.0
|
||||||
@ -14,6 +15,7 @@ require (
|
|||||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||||
github.com/Masterminds/sprig/v3 v3.2.3 // indirect
|
github.com/Masterminds/sprig/v3 v3.2.3 // indirect
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
|
github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
|
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/google/uuid v1.1.1 // indirect
|
github.com/google/uuid v1.1.1 // indirect
|
||||||
github.com/huandu/xstrings v1.3.3 // indirect
|
github.com/huandu/xstrings v1.3.3 // indirect
|
||||||
github.com/imdario/mergo v0.3.11 // indirect
|
github.com/imdario/mergo v0.3.11 // indirect
|
||||||
@ -22,10 +24,12 @@ require (
|
|||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
github.com/mitchellh/copystructure v1.0.0 // indirect
|
github.com/mitchellh/copystructure v1.0.0 // indirect
|
||||||
github.com/mitchellh/reflectwalk v1.0.0 // indirect
|
github.com/mitchellh/reflectwalk v1.0.0 // indirect
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||||
github.com/shopspring/decimal v1.2.0 // indirect
|
github.com/shopspring/decimal v1.2.0 // indirect
|
||||||
github.com/spf13/cast v1.3.1 // indirect
|
github.com/spf13/cast v1.3.1 // indirect
|
||||||
github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect
|
github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect
|
||||||
golang.org/x/crypto v0.23.0 // indirect
|
golang.org/x/crypto v0.23.0 // indirect
|
||||||
golang.org/x/net v0.25.0 // indirect
|
golang.org/x/net v0.25.0 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
1
go.sum
1
go.sum
@ -90,6 +90,7 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm
|
|||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||||
|
@ -8,7 +8,9 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/thegeeklab/wp-opentofu/tofu"
|
||||||
"github.com/thegeeklab/wp-plugin-go/v2/trace"
|
"github.com/thegeeklab/wp-plugin-go/v2/trace"
|
||||||
|
"github.com/thegeeklab/wp-plugin-go/v2/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -43,21 +45,21 @@ func (p *Plugin) run(ctx context.Context) error {
|
|||||||
|
|
||||||
func (p *Plugin) FlagsFromContext() error {
|
func (p *Plugin) FlagsFromContext() error {
|
||||||
if p.Context.String("init-option") != "" {
|
if p.Context.String("init-option") != "" {
|
||||||
initOptions := InitOptions{}
|
initOptions := tofu.InitOptions{}
|
||||||
if err := json.Unmarshal([]byte(p.Context.String("init-option")), &initOptions); err != nil {
|
if err := json.Unmarshal([]byte(p.Context.String("init-option")), &initOptions); err != nil {
|
||||||
return fmt.Errorf("cannot unmarshal init_option: %w", err)
|
return fmt.Errorf("cannot unmarshal init_option: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Settings.InitOptions = initOptions
|
p.Settings.Tofu.InitOptions = initOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.Context.String("fmt-option") != "" {
|
if p.Context.String("fmt-option") != "" {
|
||||||
fmtOptions := FmtOptions{}
|
fmtOptions := tofu.FmtOptions{}
|
||||||
if err := json.Unmarshal([]byte(p.Context.String("fmt-option")), &fmtOptions); err != nil {
|
if err := json.Unmarshal([]byte(p.Context.String("fmt-option")), &fmtOptions); err != nil {
|
||||||
return fmt.Errorf("cannot unmarshal fmt_option: %w", err)
|
return fmt.Errorf("cannot unmarshal fmt_option: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Settings.FmtOptions = fmtOptions
|
p.Settings.Tofu.FmtOptions = fmtOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -70,9 +72,9 @@ func (p *Plugin) Validate() error {
|
|||||||
p.Settings.DataDir = value
|
p.Settings.DataDir = value
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Settings.OutFile = "plan.tfout"
|
p.Settings.Tofu.OutFile = "plan.tfout"
|
||||||
if p.Settings.DataDir == ".terraform" {
|
if p.Settings.DataDir == ".terraform" {
|
||||||
p.Settings.OutFile = fmt.Sprintf("%s.plan.tfout", p.Settings.DataDir)
|
p.Settings.Tofu.OutFile = fmt.Sprintf("%s.plan.tfout", p.Settings.DataDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -80,8 +82,8 @@ func (p *Plugin) Validate() error {
|
|||||||
|
|
||||||
// Execute provides the implementation of the plugin.
|
// Execute provides the implementation of the plugin.
|
||||||
func (p *Plugin) Execute() error {
|
func (p *Plugin) Execute() error {
|
||||||
batchCmd := make([]*Cmd, 0)
|
batchCmd := make([]*types.Cmd, 0)
|
||||||
batchCmd = append(batchCmd, p.versionCommand())
|
batchCmd = append(batchCmd, p.Settings.Tofu.Version())
|
||||||
|
|
||||||
if p.Settings.TofuVersion != "" {
|
if p.Settings.TofuVersion != "" {
|
||||||
err := installPackage(p.Plugin.Network.Context, p.Plugin.Network.Client, p.Settings.TofuVersion, maxDecompressionSize)
|
err := installPackage(p.Plugin.Network.Context, p.Plugin.Network.Client, p.Settings.TofuVersion, maxDecompressionSize)
|
||||||
@ -90,29 +92,29 @@ func (p *Plugin) Execute() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
batchCmd = append(batchCmd, p.initCommand())
|
batchCmd = append(batchCmd, p.Settings.Tofu.Init())
|
||||||
batchCmd = append(batchCmd, p.getModulesCommand())
|
batchCmd = append(batchCmd, p.Settings.Tofu.GetModules())
|
||||||
|
|
||||||
for _, action := range p.Settings.Action.Value() {
|
for _, action := range p.Settings.Action.Value() {
|
||||||
switch action {
|
switch action {
|
||||||
case "fmt":
|
case "fmt":
|
||||||
batchCmd = append(batchCmd, p.fmtCommand())
|
batchCmd = append(batchCmd, p.Settings.Tofu.Fmt())
|
||||||
case "validate":
|
case "validate":
|
||||||
batchCmd = append(batchCmd, p.validateCommand())
|
batchCmd = append(batchCmd, p.Settings.Tofu.Validate())
|
||||||
case "plan":
|
case "plan":
|
||||||
batchCmd = append(batchCmd, p.planCommand(false))
|
batchCmd = append(batchCmd, p.Settings.Tofu.Plan(false))
|
||||||
case "plan-destroy":
|
case "plan-destroy":
|
||||||
batchCmd = append(batchCmd, p.planCommand(true))
|
batchCmd = append(batchCmd, p.Settings.Tofu.Plan(true))
|
||||||
case "apply":
|
case "apply":
|
||||||
batchCmd = append(batchCmd, p.applyCommand())
|
batchCmd = append(batchCmd, p.Settings.Tofu.Apply())
|
||||||
case "destroy":
|
case "destroy":
|
||||||
batchCmd = append(batchCmd, p.destroyCommand())
|
batchCmd = append(batchCmd, p.Settings.Tofu.Destroy())
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("%w: %s", ErrActionUnknown, action)
|
return fmt.Errorf("%w: %s", ErrActionUnknown, action)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := deleteDir(p.Settings.DataDir); err != nil {
|
if err := os.RemoveAll(p.Settings.DataDir); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,5 +138,5 @@ func (p *Plugin) Execute() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return deleteDir(p.Settings.DataDir)
|
return os.RemoveAll(p.Settings.DataDir)
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,9 @@ package plugin
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/thegeeklab/wp-opentofu/tofu"
|
||||||
wp "github.com/thegeeklab/wp-plugin-go/v2/plugin"
|
wp "github.com/thegeeklab/wp-plugin-go/v2/plugin"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
"golang.org/x/sys/execabs"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:generate go run ../internal/docs/main.go -output=../docs/data/data-raw.yaml
|
//go:generate go run ../internal/docs/main.go -output=../docs/data/data-raw.yaml
|
||||||
@ -19,38 +19,10 @@ type Plugin struct {
|
|||||||
// Settings for the Plugin.
|
// Settings for the Plugin.
|
||||||
type Settings struct {
|
type Settings struct {
|
||||||
Action cli.StringSlice
|
Action cli.StringSlice
|
||||||
|
|
||||||
TofuVersion string
|
|
||||||
InitOptions InitOptions
|
|
||||||
FmtOptions FmtOptions
|
|
||||||
|
|
||||||
RootDir string
|
RootDir string
|
||||||
DataDir string
|
DataDir string
|
||||||
OutFile string
|
TofuVersion string
|
||||||
Parallelism int
|
Tofu tofu.Tofu
|
||||||
Targets cli.StringSlice
|
|
||||||
Refresh bool
|
|
||||||
NoLog bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// InitOptions include options for the OpenTofu init command.
|
|
||||||
type InitOptions struct {
|
|
||||||
BackendConfig []string `json:"backend-config"`
|
|
||||||
Lock *bool `json:"lock"`
|
|
||||||
LockTimeout string `json:"lock-timeout"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// FmtOptions fmt options for the OpenTofu fmt command.
|
|
||||||
type FmtOptions struct {
|
|
||||||
List *bool `json:"list"`
|
|
||||||
Write *bool `json:"write"`
|
|
||||||
Diff *bool `json:"diff"`
|
|
||||||
Check *bool `json:"check"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Cmd struct {
|
|
||||||
*execabs.Cmd
|
|
||||||
Private bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(e wp.ExecuteFunc, build ...string) *Plugin {
|
func New(e wp.ExecuteFunc, build ...string) *Plugin {
|
||||||
@ -123,14 +95,14 @@ func Flags(settings *Settings, category string) []cli.Flag {
|
|||||||
Name: "no-log",
|
Name: "no-log",
|
||||||
Usage: "suppress tofu command output for `plan`, `apply` and `destroy` action",
|
Usage: "suppress tofu command output for `plan`, `apply` and `destroy` action",
|
||||||
EnvVars: []string{"PLUGIN_NO_LOG"},
|
EnvVars: []string{"PLUGIN_NO_LOG"},
|
||||||
Destination: &settings.NoLog,
|
Destination: &settings.Tofu.NoLog,
|
||||||
Category: category,
|
Category: category,
|
||||||
},
|
},
|
||||||
&cli.StringSliceFlag{
|
&cli.StringSliceFlag{
|
||||||
Name: "targets",
|
Name: "targets",
|
||||||
Usage: "targets to run `plan` or `apply` action on",
|
Usage: "targets to run `plan` or `apply` action on",
|
||||||
EnvVars: []string{"PLUGIN_TARGETS"},
|
EnvVars: []string{"PLUGIN_TARGETS"},
|
||||||
Destination: &settings.Targets,
|
Destination: &settings.Tofu.Targets,
|
||||||
Category: category,
|
Category: category,
|
||||||
},
|
},
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
@ -144,7 +116,7 @@ func Flags(settings *Settings, category string) []cli.Flag {
|
|||||||
Name: "refresh",
|
Name: "refresh",
|
||||||
Usage: "enables refreshing of the state before `plan` and `apply` commands",
|
Usage: "enables refreshing of the state before `plan` and `apply` commands",
|
||||||
EnvVars: []string{"PLUGIN_REFRESH"},
|
EnvVars: []string{"PLUGIN_REFRESH"},
|
||||||
Destination: &settings.Refresh,
|
Destination: &settings.Tofu.Refresh,
|
||||||
Value: true,
|
Value: true,
|
||||||
Category: category,
|
Category: category,
|
||||||
},
|
},
|
||||||
|
172
plugin/tofu.go
172
plugin/tofu.go
@ -1,172 +0,0 @@
|
|||||||
package plugin
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"golang.org/x/sys/execabs"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
tofuBin = "/usr/local/bin/tofu"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (p *Plugin) versionCommand() *Cmd {
|
|
||||||
return &Cmd{
|
|
||||||
Cmd: execabs.Command(tofuBin, "version"),
|
|
||||||
Private: p.Settings.NoLog,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Plugin) initCommand() *Cmd {
|
|
||||||
args := []string{
|
|
||||||
"init",
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, v := range p.Settings.InitOptions.BackendConfig {
|
|
||||||
args = append(args, fmt.Sprintf("-backend-config=%s", v))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fail tofu execution on prompt
|
|
||||||
args = append(args, "-input=false")
|
|
||||||
|
|
||||||
return &Cmd{
|
|
||||||
Cmd: execabs.Command(tofuBin, args...),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Plugin) getModulesCommand() *Cmd {
|
|
||||||
return &Cmd{
|
|
||||||
Cmd: execabs.Command(tofuBin, "get"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Plugin) validateCommand() *Cmd {
|
|
||||||
return &Cmd{
|
|
||||||
Cmd: execabs.Command(tofuBin, "validate"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Plugin) fmtCommand() *Cmd {
|
|
||||||
args := []string{
|
|
||||||
"fmt",
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.Settings.FmtOptions.List != nil {
|
|
||||||
args = append(args, fmt.Sprintf("-list=%t", *p.Settings.FmtOptions.List))
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.Settings.FmtOptions.Write != nil {
|
|
||||||
args = append(args, fmt.Sprintf("-write=%t", *p.Settings.FmtOptions.Write))
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.Settings.FmtOptions.Diff != nil {
|
|
||||||
args = append(args, fmt.Sprintf("-diff=%t", *p.Settings.FmtOptions.Diff))
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.Settings.FmtOptions.Check != nil {
|
|
||||||
args = append(args, fmt.Sprintf("-check=%t", *p.Settings.FmtOptions.Check))
|
|
||||||
}
|
|
||||||
|
|
||||||
return &Cmd{
|
|
||||||
Cmd: execabs.Command(tofuBin, args...),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Plugin) planCommand(destroy bool) *Cmd {
|
|
||||||
args := []string{
|
|
||||||
"plan",
|
|
||||||
}
|
|
||||||
|
|
||||||
if destroy {
|
|
||||||
args = append(args, "-destroy")
|
|
||||||
} else {
|
|
||||||
args = append(args, fmt.Sprintf("-out=%s", p.Settings.OutFile))
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, value := range p.Settings.Targets.Value() {
|
|
||||||
args = append(args, "--target", value)
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.Settings.Parallelism > 0 {
|
|
||||||
args = append(args, fmt.Sprintf("-parallelism=%d", p.Settings.Parallelism))
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.Settings.InitOptions.Lock != nil {
|
|
||||||
args = append(args, fmt.Sprintf("-lock=%t", *p.Settings.InitOptions.Lock))
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.Settings.InitOptions.LockTimeout != "" {
|
|
||||||
args = append(args, fmt.Sprintf("-lock-timeout=%s", p.Settings.InitOptions.LockTimeout))
|
|
||||||
}
|
|
||||||
|
|
||||||
if !p.Settings.Refresh {
|
|
||||||
args = append(args, "-refresh=false")
|
|
||||||
}
|
|
||||||
|
|
||||||
return &Cmd{
|
|
||||||
Cmd: execabs.Command(tofuBin, args...),
|
|
||||||
Private: p.Settings.NoLog,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Plugin) applyCommand() *Cmd {
|
|
||||||
args := []string{
|
|
||||||
"apply",
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, v := range p.Settings.Targets.Value() {
|
|
||||||
args = append(args, "--target", v)
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.Settings.Parallelism > 0 {
|
|
||||||
args = append(args, fmt.Sprintf("-parallelism=%d", p.Settings.Parallelism))
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.Settings.InitOptions.Lock != nil {
|
|
||||||
args = append(args, fmt.Sprintf("-lock=%t", *p.Settings.InitOptions.Lock))
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.Settings.InitOptions.LockTimeout != "" {
|
|
||||||
args = append(args, fmt.Sprintf("-lock-timeout=%s", p.Settings.InitOptions.LockTimeout))
|
|
||||||
}
|
|
||||||
|
|
||||||
if !p.Settings.Refresh {
|
|
||||||
args = append(args, "-refresh=false")
|
|
||||||
}
|
|
||||||
|
|
||||||
args = append(args, p.Settings.OutFile)
|
|
||||||
|
|
||||||
return &Cmd{
|
|
||||||
Cmd: execabs.Command(tofuBin, args...),
|
|
||||||
Private: p.Settings.NoLog,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Plugin) destroyCommand() *Cmd {
|
|
||||||
args := []string{
|
|
||||||
"destroy",
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, v := range p.Settings.Targets.Value() {
|
|
||||||
args = append(args, fmt.Sprintf("-target=%s", v))
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.Settings.Parallelism > 0 {
|
|
||||||
args = append(args, fmt.Sprintf("-parallelism=%d", p.Settings.Parallelism))
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.Settings.InitOptions.Lock != nil {
|
|
||||||
args = append(args, fmt.Sprintf("-lock=%t", *p.Settings.InitOptions.Lock))
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.Settings.InitOptions.LockTimeout != "" {
|
|
||||||
args = append(args, fmt.Sprintf("-lock-timeout=%s", p.Settings.InitOptions.LockTimeout))
|
|
||||||
}
|
|
||||||
|
|
||||||
args = append(args, "-auto-approve")
|
|
||||||
|
|
||||||
return &Cmd{
|
|
||||||
Cmd: execabs.Command(tofuBin, args...),
|
|
||||||
Private: p.Settings.NoLog,
|
|
||||||
}
|
|
||||||
}
|
|
@ -13,6 +13,7 @@ import (
|
|||||||
|
|
||||||
"github.com/Masterminds/semver/v3"
|
"github.com/Masterminds/semver/v3"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
|
"github.com/thegeeklab/wp-opentofu/tofu"
|
||||||
)
|
)
|
||||||
|
|
||||||
func installPackage(ctx context.Context, client *http.Client, version string, maxSize int64) error {
|
func installPackage(ctx context.Context, client *http.Client, version string, maxSize int64) error {
|
||||||
@ -34,7 +35,7 @@ func installPackage(ctx context.Context, client *http.Client, version string, ma
|
|||||||
}
|
}
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
_ = deleteDir(tmpdir)
|
_ = os.RemoveAll(tmpdir)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
log.Debug().
|
log.Debug().
|
||||||
@ -51,7 +52,7 @@ func installPackage(ctx context.Context, client *http.Client, version string, ma
|
|||||||
return fmt.Errorf("failed to unzip: %w", err)
|
return fmt.Errorf("failed to unzip: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := os.Rename(filepath.Join(tmpdir, "tofu"), tofuBin); err != nil {
|
if err := os.Rename(filepath.Join(tmpdir, "tofu"), tofu.TofuBin); err != nil {
|
||||||
return fmt.Errorf("failed to rename: %w", err)
|
return fmt.Errorf("failed to rename: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,7 +170,3 @@ func sanitizeArchivePath(d, t string) (string, error) {
|
|||||||
|
|
||||||
return "", fmt.Errorf("%w: %v", ErrTaintedPath, t)
|
return "", fmt.Errorf("%w: %v", ErrTaintedPath, t)
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteDir(path string) error {
|
|
||||||
return os.RemoveAll(path)
|
|
||||||
}
|
|
||||||
|
200
tofu/tofu.go
Normal file
200
tofu/tofu.go
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
package tofu
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/thegeeklab/wp-plugin-go/v2/types"
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
"golang.org/x/sys/execabs"
|
||||||
|
)
|
||||||
|
|
||||||
|
const TofuBin = "/usr/local/bin/tofu"
|
||||||
|
|
||||||
|
type Tofu struct {
|
||||||
|
InitOptions InitOptions
|
||||||
|
FmtOptions FmtOptions
|
||||||
|
|
||||||
|
OutFile string
|
||||||
|
Parallelism int
|
||||||
|
Targets cli.StringSlice
|
||||||
|
Refresh bool
|
||||||
|
NoLog bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// InitOptions include options for the OpenTofu init command.
|
||||||
|
type InitOptions struct {
|
||||||
|
BackendConfig []string `json:"backend-config"`
|
||||||
|
Lock *bool `json:"lock"`
|
||||||
|
LockTimeout string `json:"lock-timeout"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// FmtOptions fmt options for the OpenTofu fmt command.
|
||||||
|
type FmtOptions struct {
|
||||||
|
List *bool `json:"list"`
|
||||||
|
Write *bool `json:"write"`
|
||||||
|
Diff *bool `json:"diff"`
|
||||||
|
Check *bool `json:"check"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Tofu) Version() *types.Cmd {
|
||||||
|
return &types.Cmd{
|
||||||
|
Cmd: execabs.Command(TofuBin, "version"),
|
||||||
|
Private: t.NoLog,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Tofu) Init() *types.Cmd {
|
||||||
|
args := []string{
|
||||||
|
"init",
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range t.InitOptions.BackendConfig {
|
||||||
|
args = append(args, fmt.Sprintf("-backend-config=%s", v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fail tofu execution on prompt
|
||||||
|
args = append(args, "-input=false")
|
||||||
|
|
||||||
|
return &types.Cmd{
|
||||||
|
Cmd: execabs.Command(TofuBin, args...),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Tofu) GetModules() *types.Cmd {
|
||||||
|
return &types.Cmd{
|
||||||
|
Cmd: execabs.Command(TofuBin, "get"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Tofu) Validate() *types.Cmd {
|
||||||
|
return &types.Cmd{
|
||||||
|
Cmd: execabs.Command(TofuBin, "validate"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Tofu) Fmt() *types.Cmd {
|
||||||
|
args := []string{
|
||||||
|
"fmt",
|
||||||
|
}
|
||||||
|
|
||||||
|
if t.FmtOptions.List != nil {
|
||||||
|
args = append(args, fmt.Sprintf("-list=%t", *t.FmtOptions.List))
|
||||||
|
}
|
||||||
|
|
||||||
|
if t.FmtOptions.Write != nil {
|
||||||
|
args = append(args, fmt.Sprintf("-write=%t", *t.FmtOptions.Write))
|
||||||
|
}
|
||||||
|
|
||||||
|
if t.FmtOptions.Diff != nil {
|
||||||
|
args = append(args, fmt.Sprintf("-diff=%t", *t.FmtOptions.Diff))
|
||||||
|
}
|
||||||
|
|
||||||
|
if t.FmtOptions.Check != nil {
|
||||||
|
args = append(args, fmt.Sprintf("-check=%t", *t.FmtOptions.Check))
|
||||||
|
}
|
||||||
|
|
||||||
|
return &types.Cmd{
|
||||||
|
Cmd: execabs.Command(TofuBin, args...),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Tofu) Plan(destroy bool) *types.Cmd {
|
||||||
|
args := []string{
|
||||||
|
"plan",
|
||||||
|
}
|
||||||
|
|
||||||
|
if destroy {
|
||||||
|
args = append(args, "-destroy")
|
||||||
|
} else if t.OutFile != "" {
|
||||||
|
args = append(args, fmt.Sprintf("-out=%s", t.OutFile))
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, value := range t.Targets.Value() {
|
||||||
|
args = append(args, "--target", value)
|
||||||
|
}
|
||||||
|
|
||||||
|
if t.Parallelism > 0 {
|
||||||
|
args = append(args, fmt.Sprintf("-parallelism=%d", t.Parallelism))
|
||||||
|
}
|
||||||
|
|
||||||
|
if t.InitOptions.Lock != nil {
|
||||||
|
args = append(args, fmt.Sprintf("-lock=%t", *t.InitOptions.Lock))
|
||||||
|
}
|
||||||
|
|
||||||
|
if t.InitOptions.LockTimeout != "" {
|
||||||
|
args = append(args, fmt.Sprintf("-lock-timeout=%s", t.InitOptions.LockTimeout))
|
||||||
|
}
|
||||||
|
|
||||||
|
if !t.Refresh {
|
||||||
|
args = append(args, "-refresh=false")
|
||||||
|
}
|
||||||
|
|
||||||
|
return &types.Cmd{
|
||||||
|
Cmd: execabs.Command(TofuBin, args...),
|
||||||
|
Private: t.NoLog,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Tofu) Apply() *types.Cmd {
|
||||||
|
args := []string{
|
||||||
|
"apply",
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range t.Targets.Value() {
|
||||||
|
args = append(args, "--target", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
if t.Parallelism > 0 {
|
||||||
|
args = append(args, fmt.Sprintf("-parallelism=%d", t.Parallelism))
|
||||||
|
}
|
||||||
|
|
||||||
|
if t.InitOptions.Lock != nil {
|
||||||
|
args = append(args, fmt.Sprintf("-lock=%t", *t.InitOptions.Lock))
|
||||||
|
}
|
||||||
|
|
||||||
|
if t.InitOptions.LockTimeout != "" {
|
||||||
|
args = append(args, fmt.Sprintf("-lock-timeout=%s", t.InitOptions.LockTimeout))
|
||||||
|
}
|
||||||
|
|
||||||
|
if !t.Refresh {
|
||||||
|
args = append(args, "-refresh=false")
|
||||||
|
}
|
||||||
|
|
||||||
|
if t.OutFile != "" {
|
||||||
|
args = append(args, t.OutFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &types.Cmd{
|
||||||
|
Cmd: execabs.Command(TofuBin, args...),
|
||||||
|
Private: t.NoLog,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Tofu) Destroy() *types.Cmd {
|
||||||
|
args := []string{
|
||||||
|
"destroy",
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range t.Targets.Value() {
|
||||||
|
args = append(args, fmt.Sprintf("-target=%s", v))
|
||||||
|
}
|
||||||
|
|
||||||
|
if t.Parallelism > 0 {
|
||||||
|
args = append(args, fmt.Sprintf("-parallelism=%d", t.Parallelism))
|
||||||
|
}
|
||||||
|
|
||||||
|
if t.InitOptions.Lock != nil {
|
||||||
|
args = append(args, fmt.Sprintf("-lock=%t", *t.InitOptions.Lock))
|
||||||
|
}
|
||||||
|
|
||||||
|
if t.InitOptions.LockTimeout != "" {
|
||||||
|
args = append(args, fmt.Sprintf("-lock-timeout=%s", t.InitOptions.LockTimeout))
|
||||||
|
}
|
||||||
|
|
||||||
|
args = append(args, "-auto-approve")
|
||||||
|
|
||||||
|
return &types.Cmd{
|
||||||
|
Cmd: execabs.Command(TofuBin, args...),
|
||||||
|
Private: t.NoLog,
|
||||||
|
}
|
||||||
|
}
|
545
tofu/tofu_test.go
Normal file
545
tofu/tofu_test.go
Normal file
@ -0,0 +1,545 @@
|
|||||||
|
package tofu
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func boolPtr(b bool) *bool {
|
||||||
|
return &b
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTofu_Version(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
tofu *Tofu
|
||||||
|
want []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "test version command",
|
||||||
|
tofu: &Tofu{},
|
||||||
|
want: []string{TofuBin, "version"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
cmd := tt.tofu.Version()
|
||||||
|
assert.Equal(t, tt.want, cmd.Cmd.Args)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTofu_Init(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
tofu *Tofu
|
||||||
|
want []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "init with no backend config",
|
||||||
|
tofu: &Tofu{},
|
||||||
|
want: []string{
|
||||||
|
TofuBin,
|
||||||
|
"init",
|
||||||
|
"-input=false",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "init with single backend config",
|
||||||
|
tofu: &Tofu{
|
||||||
|
InitOptions: InitOptions{
|
||||||
|
BackendConfig: []string{"key=value"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: []string{
|
||||||
|
TofuBin,
|
||||||
|
"init",
|
||||||
|
"-backend-config=key=value",
|
||||||
|
"-input=false",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "init with multiple backend configs",
|
||||||
|
tofu: &Tofu{
|
||||||
|
InitOptions: InitOptions{
|
||||||
|
BackendConfig: []string{"key1=value1", "key2=value2"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: []string{
|
||||||
|
TofuBin,
|
||||||
|
"init",
|
||||||
|
"-backend-config=key1=value1",
|
||||||
|
"-backend-config=key2=value2",
|
||||||
|
"-input=false",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
cmd := tt.tofu.Init()
|
||||||
|
assert.Equal(t, tt.want, cmd.Cmd.Args)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTofu_GetModules(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
tofu *Tofu
|
||||||
|
want []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "get modules command",
|
||||||
|
tofu: &Tofu{},
|
||||||
|
want: []string{TofuBin, "get"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
cmd := tt.tofu.GetModules()
|
||||||
|
assert.Equal(t, tt.want, cmd.Cmd.Args)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTofu_Validate(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
tofu *Tofu
|
||||||
|
want []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "validate command",
|
||||||
|
tofu: &Tofu{},
|
||||||
|
want: []string{TofuBin, "validate"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
cmd := tt.tofu.Validate()
|
||||||
|
assert.Equal(t, tt.want, cmd.Cmd.Args)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTofu_Fmt(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
tofu *Tofu
|
||||||
|
want []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "fmt with no options",
|
||||||
|
tofu: &Tofu{},
|
||||||
|
want: []string{
|
||||||
|
TofuBin,
|
||||||
|
"fmt",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "fmt with list option",
|
||||||
|
tofu: &Tofu{
|
||||||
|
FmtOptions: FmtOptions{
|
||||||
|
List: boolPtr(true),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: []string{
|
||||||
|
TofuBin,
|
||||||
|
"fmt",
|
||||||
|
"-list=true",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "fmt with write option",
|
||||||
|
tofu: &Tofu{
|
||||||
|
FmtOptions: FmtOptions{
|
||||||
|
Write: boolPtr(true),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: []string{
|
||||||
|
TofuBin,
|
||||||
|
"fmt",
|
||||||
|
"-write=true",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "fmt with diff option",
|
||||||
|
tofu: &Tofu{
|
||||||
|
FmtOptions: FmtOptions{
|
||||||
|
Diff: boolPtr(true),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: []string{
|
||||||
|
TofuBin,
|
||||||
|
"fmt",
|
||||||
|
"-diff=true",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "fmt with check option",
|
||||||
|
tofu: &Tofu{
|
||||||
|
FmtOptions: FmtOptions{
|
||||||
|
Check: boolPtr(true),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: []string{
|
||||||
|
TofuBin,
|
||||||
|
"fmt",
|
||||||
|
"-check=true",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "fmt with multiple options",
|
||||||
|
tofu: &Tofu{
|
||||||
|
FmtOptions: FmtOptions{
|
||||||
|
List: boolPtr(true),
|
||||||
|
Write: boolPtr(true),
|
||||||
|
Diff: boolPtr(true),
|
||||||
|
Check: boolPtr(true),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: []string{
|
||||||
|
TofuBin,
|
||||||
|
"fmt",
|
||||||
|
"-list=true",
|
||||||
|
"-write=true",
|
||||||
|
"-diff=true",
|
||||||
|
"-check=true",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
cmd := tt.tofu.Fmt()
|
||||||
|
assert.Equal(t, tt.want, cmd.Cmd.Args)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTofu_Plan(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
tofu *Tofu
|
||||||
|
destroy bool
|
||||||
|
want []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "plan with no options",
|
||||||
|
tofu: &Tofu{},
|
||||||
|
destroy: false,
|
||||||
|
want: []string{
|
||||||
|
TofuBin,
|
||||||
|
"plan",
|
||||||
|
"-refresh=false",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "plan with output options",
|
||||||
|
tofu: &Tofu{
|
||||||
|
OutFile: "plan.tfout",
|
||||||
|
},
|
||||||
|
destroy: false,
|
||||||
|
want: []string{
|
||||||
|
TofuBin,
|
||||||
|
"plan",
|
||||||
|
"-out=plan.tfout",
|
||||||
|
"-refresh=false",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "plan with destroy option",
|
||||||
|
tofu: &Tofu{},
|
||||||
|
destroy: true,
|
||||||
|
want: []string{
|
||||||
|
TofuBin,
|
||||||
|
"plan",
|
||||||
|
"-destroy",
|
||||||
|
"-refresh=false",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "plan with targets",
|
||||||
|
tofu: &Tofu{
|
||||||
|
Targets: *cli.NewStringSlice("target1", "target2"),
|
||||||
|
},
|
||||||
|
destroy: false,
|
||||||
|
want: []string{
|
||||||
|
TofuBin,
|
||||||
|
"plan",
|
||||||
|
"--target", "target1",
|
||||||
|
"--target", "target2",
|
||||||
|
"-refresh=false",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "plan with parallelism",
|
||||||
|
tofu: &Tofu{
|
||||||
|
Parallelism: 10,
|
||||||
|
},
|
||||||
|
destroy: false,
|
||||||
|
want: []string{
|
||||||
|
TofuBin,
|
||||||
|
"plan",
|
||||||
|
"-parallelism=10",
|
||||||
|
"-refresh=false",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "plan with lock option",
|
||||||
|
tofu: &Tofu{
|
||||||
|
InitOptions: InitOptions{
|
||||||
|
Lock: boolPtr(true),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
destroy: false,
|
||||||
|
want: []string{
|
||||||
|
TofuBin,
|
||||||
|
"plan",
|
||||||
|
"-lock=true",
|
||||||
|
"-refresh=false",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "plan with lock timeout",
|
||||||
|
tofu: &Tofu{
|
||||||
|
InitOptions: InitOptions{
|
||||||
|
LockTimeout: "10s",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
destroy: false,
|
||||||
|
want: []string{
|
||||||
|
TofuBin,
|
||||||
|
"plan",
|
||||||
|
"-lock-timeout=10s",
|
||||||
|
"-refresh=false",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "plan with refresh option",
|
||||||
|
tofu: &Tofu{
|
||||||
|
Refresh: true,
|
||||||
|
},
|
||||||
|
destroy: false,
|
||||||
|
want: []string{
|
||||||
|
TofuBin,
|
||||||
|
"plan",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
cmd := tt.tofu.Plan(tt.destroy)
|
||||||
|
assert.Equal(t, tt.want, cmd.Cmd.Args)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTofu_Apply(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
tofu *Tofu
|
||||||
|
want []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "apply with no options",
|
||||||
|
tofu: &Tofu{},
|
||||||
|
want: []string{
|
||||||
|
TofuBin,
|
||||||
|
"apply",
|
||||||
|
"-refresh=false",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "apply with targets",
|
||||||
|
tofu: &Tofu{
|
||||||
|
Targets: *cli.NewStringSlice("target1", "target2"),
|
||||||
|
},
|
||||||
|
want: []string{
|
||||||
|
TofuBin,
|
||||||
|
"apply",
|
||||||
|
"--target", "target1",
|
||||||
|
"--target", "target2",
|
||||||
|
"-refresh=false",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "apply with parallelism",
|
||||||
|
tofu: &Tofu{
|
||||||
|
Parallelism: 10,
|
||||||
|
},
|
||||||
|
want: []string{
|
||||||
|
TofuBin,
|
||||||
|
"apply",
|
||||||
|
"-parallelism=10",
|
||||||
|
"-refresh=false",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "apply with lock option",
|
||||||
|
tofu: &Tofu{
|
||||||
|
InitOptions: InitOptions{
|
||||||
|
Lock: boolPtr(true),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: []string{
|
||||||
|
TofuBin,
|
||||||
|
"apply",
|
||||||
|
"-lock=true",
|
||||||
|
"-refresh=false",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "apply with lock timeout",
|
||||||
|
tofu: &Tofu{
|
||||||
|
InitOptions: InitOptions{
|
||||||
|
LockTimeout: "10s",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: []string{
|
||||||
|
TofuBin,
|
||||||
|
"apply",
|
||||||
|
"-lock-timeout=10s",
|
||||||
|
"-refresh=false",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "apply with refresh option",
|
||||||
|
tofu: &Tofu{
|
||||||
|
Refresh: true,
|
||||||
|
},
|
||||||
|
want: []string{
|
||||||
|
TofuBin,
|
||||||
|
"apply",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "apply with output file",
|
||||||
|
tofu: &Tofu{
|
||||||
|
OutFile: "out.tfout",
|
||||||
|
},
|
||||||
|
want: []string{
|
||||||
|
TofuBin,
|
||||||
|
"apply",
|
||||||
|
"-refresh=false",
|
||||||
|
"out.tfout",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "apply with no log",
|
||||||
|
tofu: &Tofu{
|
||||||
|
NoLog: true,
|
||||||
|
},
|
||||||
|
want: []string{
|
||||||
|
TofuBin,
|
||||||
|
"apply",
|
||||||
|
"-refresh=false",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
cmd := tt.tofu.Apply()
|
||||||
|
assert.Equal(t, tt.want, cmd.Cmd.Args)
|
||||||
|
assert.Equal(t, tt.tofu.NoLog, cmd.Private)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTofu_Destroy(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
tofu *Tofu
|
||||||
|
want []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "destroy with no options",
|
||||||
|
tofu: &Tofu{},
|
||||||
|
want: []string{
|
||||||
|
TofuBin,
|
||||||
|
"destroy",
|
||||||
|
"-auto-approve",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "destroy with targets",
|
||||||
|
tofu: &Tofu{
|
||||||
|
Targets: *cli.NewStringSlice("target1", "target2"),
|
||||||
|
},
|
||||||
|
want: []string{
|
||||||
|
TofuBin,
|
||||||
|
"destroy",
|
||||||
|
"-target=target1",
|
||||||
|
"-target=target2",
|
||||||
|
"-auto-approve",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "destroy with parallelism",
|
||||||
|
tofu: &Tofu{
|
||||||
|
Parallelism: 10,
|
||||||
|
},
|
||||||
|
want: []string{
|
||||||
|
TofuBin,
|
||||||
|
"destroy",
|
||||||
|
"-parallelism=10",
|
||||||
|
"-auto-approve",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "destroy with lock option",
|
||||||
|
tofu: &Tofu{
|
||||||
|
InitOptions: InitOptions{
|
||||||
|
Lock: boolPtr(true),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: []string{
|
||||||
|
TofuBin,
|
||||||
|
"destroy",
|
||||||
|
"-lock=true",
|
||||||
|
"-auto-approve",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "destroy with lock timeout",
|
||||||
|
tofu: &Tofu{
|
||||||
|
InitOptions: InitOptions{
|
||||||
|
LockTimeout: "10s",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: []string{
|
||||||
|
TofuBin,
|
||||||
|
"destroy",
|
||||||
|
"-lock-timeout=10s",
|
||||||
|
"-auto-approve",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "destroy with no log",
|
||||||
|
tofu: &Tofu{
|
||||||
|
NoLog: true,
|
||||||
|
},
|
||||||
|
want: []string{
|
||||||
|
TofuBin,
|
||||||
|
"destroy",
|
||||||
|
"-auto-approve",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
cmd := tt.tofu.Destroy()
|
||||||
|
assert.Equal(t, tt.want, cmd.Cmd.Args)
|
||||||
|
assert.Equal(t, tt.tofu.NoLog, cmd.Private)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user