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 providers lock Command #203

Merged
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
26 changes: 26 additions & 0 deletions tfexec/internal/e2etest/providers_lock_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package e2etest

import (
"context"
"testing"

"github.com/hashicorp/go-version"

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

func TestProvidersLock(t *testing.T) {
runTestVersions(t, []string{testutil.Latest014, testutil.Latest015, testutil.Latest_v1}, "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.ProvidersLock(context.Background())
if err != nil {
t.Fatalf("error running provider lock: %s", err)
}
})

}
36 changes: 36 additions & 0 deletions tfexec/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,15 @@ func DryRun(dryRun bool) *DryRunOption {
return &DryRunOption{dryRun}
}

type FSMirrorOption struct {
fsMirror string
}

// FSMirror represents the -fs-mirror option (path to filesystem mirror directory)
func FSMirror(fsMirror string) *FSMirrorOption {
return &FSMirrorOption{fsMirror}
}

type ForceOption struct {
force bool
}
Expand Down Expand Up @@ -178,6 +187,15 @@ func LockTimeout(lockTimeout string) *LockTimeoutOption {
return &LockTimeoutOption{lockTimeout}
}

type NetMirrorOption struct {
netMirror string
}

// NetMirror represents the -net-mirror option (base URL of a network mirror)
func NetMirror(netMirror string) *NetMirrorOption {
return &NetMirrorOption{netMirror}
}

type OutOption struct {
path string
}
Expand All @@ -194,6 +212,15 @@ func Parallelism(n int) *ParallelismOption {
return &ParallelismOption{n}
}

type PlatformOption struct {
platform string
}

// Platform represents the -platform flag which is an os_arch string
func Platform(platform string) *PlatformOption {
return &PlatformOption{platform}
}

type PluginDirOption struct {
pluginDir string
}
Expand All @@ -202,6 +229,15 @@ func PluginDir(pluginDir string) *PluginDirOption {
return &PluginDirOption{pluginDir}
}

type ProviderOption struct {
provider string
}

// Provider represents the positional argument (provider source address)
func Provider(providers string) *ProviderOption {
return &ProviderOption{providers}
}

type ReattachInfo map[string]ReattachConfig

// ReattachConfig holds the information Terraform needs to be able to attach
Expand Down
82 changes: 82 additions & 0 deletions tfexec/providers_lock.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package tfexec

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

type providersLockConfig struct {
fsMirror string
netMirror string
platforms []string
providers []string
}

var defaultProvidersLockOptions = providersLockConfig{}

type ProvidersLockOption interface {
configureProvidersLock(*providersLockConfig)
}

func (opt *FSMirrorOption) configureProvidersLock(conf *providersLockConfig) {
conf.fsMirror = opt.fsMirror
}

func (opt *NetMirrorOption) configureProvidersLock(conf *providersLockConfig) {
conf.netMirror = opt.netMirror
}

func (opt *PlatformOption) configureProvidersLock(conf *providersLockConfig) {
conf.platforms = append(conf.platforms, opt.platform)
}

func (opt *ProviderOption) configureProvidersLock(conf *providersLockConfig) {
conf.providers = append(conf.providers, opt.provider)
}

// ProvidersLock represents the `terraform providers lock` command
func (tf *Terraform) ProvidersLock(ctx context.Context, opts ...ProvidersLockOption) error {
err := tf.compatible(ctx, tf0_14_0, nil)
if err != nil {
return fmt.Errorf("terraform providers lock was added in 0.14.0: %w", err)
}

lockCmd := tf.providersLockCmd(ctx, opts...)

err = tf.runTerraformCmd(ctx, lockCmd)
if err != nil {
return err
}

return err
}

func (tf *Terraform) providersLockCmd(ctx context.Context, opts ...ProvidersLockOption) *exec.Cmd {
c := defaultProvidersLockOptions

for _, o := range opts {
o.configureProvidersLock(&c)
}
args := []string{"providers", "lock"}

// string options, only pass if set
if c.fsMirror != "" {
args = append(args, "-fs-mirror="+c.fsMirror)
}

if c.netMirror != "" {
args = append(args, "-net-mirror="+c.netMirror)
}

for _, p := range c.platforms {
args = append(args, "-platform="+p)
}

// positional providers argument
for _, p := range c.providers {
args = append(args, p)
}

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

import (
"context"
"testing"

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

func TestProvidersLockCmd(t *testing.T) {
td := testTempDir(t)

tf, err := NewTerraform(td, tfVersion(t, testutil.Latest012))
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) {
lockCmd := tf.providersLockCmd(context.Background())

assertCmd(t, []string{
"providers",
"lock",
}, nil, lockCmd)
})

t.Run("override all defaults", func(t *testing.T) {
lockCmd := tf.providersLockCmd(context.Background(), FSMirror("test"), NetMirror("test"), Platform("linux_amd64"), Provider("workingdir"))

assertCmd(t, []string{
"providers",
"lock",
"-fs-mirror=test",
"-net-mirror=test",
"-platform=linux_amd64",
"workingdir",
}, nil, lockCmd)
})
}