Create separate Terraform workspace directory

This commit is contained in:
Nils Hanke 2022-11-14 18:18:58 +01:00 committed by Nils Hanke
parent 7f5a1dd901
commit 4a2cba988c
10 changed files with 50 additions and 60 deletions

View file

@ -11,6 +11,7 @@ import (
"errors"
"io/fs"
"path"
"path/filepath"
"strings"
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
@ -24,7 +25,7 @@ var terraformFS embed.FS
// prepareWorkspace loads the embedded Terraform files,
// and writes them into the workspace.
func prepareWorkspace(fileHandler file.Handler, provider cloudprovider.Provider) error {
func prepareWorkspace(fileHandler file.Handler, provider cloudprovider.Provider, workingDir string) error {
// use path.Join to ensure no forward slashes are used to read the embedded FS
rootDir := path.Join("terraform", strings.ToLower(provider.String()))
return fs.WalkDir(terraformFS, rootDir, func(path string, d fs.DirEntry, err error) error {
@ -39,27 +40,13 @@ func prepareWorkspace(fileHandler file.Handler, provider cloudprovider.Provider)
if err != nil {
return err
}
fileName := strings.TrimPrefix(path, rootDir+"/")
fileName := strings.Replace(filepath.Join(workingDir, path), rootDir+"/", "", 1)
return fileHandler.Write(fileName, content, file.OptMkdirAll)
})
}
// cleanUpWorkspace removes files that were loaded into the workspace.
func cleanUpWorkspace(fileHandler file.Handler) error {
// try to remove any terraform files in the workspace
for _, csp := range []string{"aws", "azure", "gcp", "qemu"} {
rootDir := path.Join("terraform", csp)
if err := fs.WalkDir(terraformFS, rootDir, func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
fileName := strings.TrimPrefix(path, rootDir+"/")
return ignoreFileNotFoundErr(fileHandler.RemoveAll(fileName))
}); err != nil {
return err
}
}
return nil
func cleanUpWorkspace(fileHandler file.Handler, workingDir string) error {
return ignoreFileNotFoundErr(fileHandler.RemoveAll(workingDir))
}
// ignoreFileNotFoundErr ignores the error if it is a file not found error.

View file

@ -8,9 +8,11 @@ package terraform
import (
"io/fs"
"path/filepath"
"testing"
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/v2/internal/constants"
"github.com/edgelesssys/constellation/v2/internal/file"
"github.com/spf13/afero"
"github.com/stretchr/testify/assert"
@ -58,12 +60,12 @@ func TestLoader(t *testing.T) {
file := file.NewHandler(afero.NewMemMapFs())
err := prepareWorkspace(file, tc.provider)
err := prepareWorkspace(file, tc.provider, constants.TerraformWorkingDir)
require.NoError(err)
checkFiles(t, file, func(err error) { assert.NoError(err) }, tc.fileList)
err = cleanUpWorkspace(file)
err = cleanUpWorkspace(file, constants.TerraformWorkingDir)
require.NoError(err)
checkFiles(t, file, func(err error) { assert.ErrorIs(err, fs.ErrNotExist) }, tc.fileList)
@ -74,7 +76,8 @@ func TestLoader(t *testing.T) {
func checkFiles(t *testing.T, file file.Handler, assertion func(error), files []string) {
t.Helper()
for _, f := range files {
_, err := file.Stat(f)
path := filepath.Join(constants.TerraformWorkingDir, f)
_, err := file.Stat(path)
assertion(err)
}
}

View file

@ -9,6 +9,7 @@ package terraform
import (
"context"
"errors"
"path/filepath"
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/v2/internal/file"
@ -32,23 +33,27 @@ const (
type Client struct {
tf tfInterface
file file.Handler
remove func()
file file.Handler
workingDir string
remove func()
}
// New sets up a new Client for Terraform.
func New(ctx context.Context) (*Client, error) {
tf, remove, err := GetExecutable(ctx, ".")
func New(ctx context.Context, workingDir string) (*Client, error) {
file := file.NewHandler(afero.NewOsFs())
if err := file.MkdirAll(workingDir); err != nil {
return nil, err
}
tf, remove, err := GetExecutable(ctx, workingDir)
if err != nil {
return nil, err
}
file := file.NewHandler(afero.NewOsFs())
return &Client{
tf: tf,
remove: remove,
file: file,
tf: tf,
remove: remove,
file: file,
workingDir: workingDir,
}, nil
}
@ -56,7 +61,7 @@ func New(ctx context.Context) (*Client, error) {
func (c *Client) CreateCluster(
ctx context.Context, provider cloudprovider.Provider, name string, vars Variables,
) (string, error) {
if err := prepareWorkspace(c.file, provider); err != nil {
if err := prepareWorkspace(c.file, provider, c.workingDir); err != nil {
return "", err
}
@ -64,7 +69,7 @@ func (c *Client) CreateCluster(
return "", err
}
if err := c.file.Write(terraformVarsFile, []byte(vars.String())); err != nil {
if err := c.file.Write(filepath.Join(c.workingDir, terraformVarsFile), []byte(vars.String())); err != nil {
return "", err
}
@ -101,23 +106,7 @@ func (c *Client) RemoveInstaller() {
// CleanUpWorkspace removes terraform files from the current directory.
func (c *Client) CleanUpWorkspace() error {
if err := cleanUpWorkspace(c.file); err != nil {
return err
}
if err := ignoreFileNotFoundErr(c.file.Remove("terraform.tfvars")); err != nil {
return err
}
if err := ignoreFileNotFoundErr(c.file.Remove("terraform.tfstate")); err != nil {
return err
}
if err := ignoreFileNotFoundErr(c.file.Remove("terraform.tfstate.backup")); err != nil {
return err
}
if err := ignoreFileNotFoundErr(c.file.Remove(".terraform.lock.hcl")); err != nil {
return err
}
if err := ignoreFileNotFoundErr(c.file.RemoveAll(".terraform")); err != nil {
if err := cleanUpWorkspace(c.file, c.workingDir); err != nil {
return err
}

View file

@ -10,9 +10,11 @@ import (
"context"
"errors"
"io/fs"
"path/filepath"
"testing"
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/v2/internal/constants"
"github.com/edgelesssys/constellation/v2/internal/file"
"github.com/hashicorp/terraform-exec/tfexec"
tfjson "github.com/hashicorp/terraform-json"
@ -122,8 +124,9 @@ func TestCreateCluster(t *testing.T) {
assert := assert.New(t)
c := &Client{
tf: tc.tf,
file: file.NewHandler(tc.fs),
tf: tc.tf,
file: file.NewHandler(tc.fs),
workingDir: constants.TerraformWorkingDir,
}
ip, err := c.CreateCluster(context.Background(), tc.provider, "test", tc.vars)
@ -205,8 +208,9 @@ func TestCleanupWorkspace(t *testing.T) {
require.NoError(tc.prepareFS(file))
c := &Client{
file: file,
tf: &stubTerraform{},
file: file,
tf: &stubTerraform{},
workingDir: constants.TerraformWorkingDir,
}
err := c.CleanUpWorkspace()
@ -215,11 +219,11 @@ func TestCleanupWorkspace(t *testing.T) {
return
}
assert.NoError(err)
_, err = file.Stat("terraform.tfvars")
_, err = file.Stat(filepath.Join(c.workingDir, "terraform.tfvars"))
assert.ErrorIs(err, fs.ErrNotExist)
_, err = file.Stat("terraform.tfstate")
_, err = file.Stat(filepath.Join(c.workingDir, "terraform.tfstate"))
assert.ErrorIs(err, fs.ErrNotExist)
_, err = file.Stat("terraform.tfstate.backup")
_, err = file.Stat(filepath.Join(c.workingDir, "terraform.tfstate.backup"))
assert.ErrorIs(err, fs.ErrNotExist)
})
}