2022-09-26 09:52:31 -04:00
|
|
|
/*
|
|
|
|
Copyright (c) Edgeless Systems GmbH
|
|
|
|
|
|
|
|
SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
*/
|
|
|
|
|
|
|
|
package terraform
|
|
|
|
|
|
|
|
import (
|
|
|
|
"io/fs"
|
2022-12-07 05:48:54 -05:00
|
|
|
"path"
|
2022-11-14 12:18:58 -05:00
|
|
|
"path/filepath"
|
2022-12-07 05:48:54 -05:00
|
|
|
"strings"
|
2022-09-26 09:52:31 -04:00
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
2022-11-14 12:18:58 -05:00
|
|
|
"github.com/edgelesssys/constellation/v2/internal/constants"
|
2022-09-26 09:52:31 -04:00
|
|
|
"github.com/edgelesssys/constellation/v2/internal/file"
|
|
|
|
"github.com/spf13/afero"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
2023-05-22 07:31:20 -04:00
|
|
|
func TestPrepareWorkspace(t *testing.T) {
|
2022-09-26 09:52:31 -04:00
|
|
|
testCases := map[string]struct {
|
2022-12-07 05:48:54 -05:00
|
|
|
pathBase string
|
2022-11-14 13:15:10 -05:00
|
|
|
provider cloudprovider.Provider
|
|
|
|
fileList []string
|
|
|
|
testAlreadyUnpacked bool
|
2022-09-26 09:52:31 -04:00
|
|
|
}{
|
2022-12-07 05:48:54 -05:00
|
|
|
"awsCluster": {
|
|
|
|
pathBase: "terraform",
|
2022-10-21 06:24:18 -04:00
|
|
|
provider: cloudprovider.AWS,
|
|
|
|
fileList: []string{
|
|
|
|
"main.tf",
|
|
|
|
"variables.tf",
|
|
|
|
"outputs.tf",
|
|
|
|
"modules",
|
|
|
|
},
|
|
|
|
},
|
2022-12-07 05:48:54 -05:00
|
|
|
"gcpCluster": {
|
|
|
|
pathBase: "terraform",
|
2022-10-21 06:24:18 -04:00
|
|
|
provider: cloudprovider.GCP,
|
|
|
|
fileList: []string{
|
|
|
|
"main.tf",
|
|
|
|
"variables.tf",
|
|
|
|
"outputs.tf",
|
|
|
|
"modules",
|
|
|
|
},
|
|
|
|
},
|
2022-12-07 05:48:54 -05:00
|
|
|
"qemuCluster": {
|
|
|
|
pathBase: "terraform",
|
2022-09-26 09:52:31 -04:00
|
|
|
provider: cloudprovider.QEMU,
|
|
|
|
fileList: []string{
|
|
|
|
"main.tf",
|
|
|
|
"variables.tf",
|
|
|
|
"outputs.tf",
|
|
|
|
"modules",
|
|
|
|
},
|
|
|
|
},
|
2022-12-07 05:48:54 -05:00
|
|
|
"gcpIAM": {
|
|
|
|
pathBase: path.Join("terraform", "iam"),
|
|
|
|
provider: cloudprovider.GCP,
|
|
|
|
fileList: []string{
|
|
|
|
"main.tf",
|
|
|
|
"variables.tf",
|
|
|
|
"outputs.tf",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"azureIAM": {
|
|
|
|
pathBase: path.Join("terraform", "iam"),
|
|
|
|
provider: cloudprovider.Azure,
|
|
|
|
fileList: []string{
|
|
|
|
"main.tf",
|
|
|
|
"variables.tf",
|
|
|
|
"outputs.tf",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"awsIAM": {
|
|
|
|
pathBase: path.Join("terraform", "iam"),
|
|
|
|
provider: cloudprovider.AWS,
|
|
|
|
fileList: []string{
|
|
|
|
"main.tf",
|
|
|
|
"variables.tf",
|
|
|
|
"outputs.tf",
|
|
|
|
},
|
|
|
|
},
|
2022-11-14 13:15:10 -05:00
|
|
|
"continue on (partially) unpacked": {
|
2022-12-07 05:48:54 -05:00
|
|
|
pathBase: "terraform",
|
2022-11-14 13:15:10 -05:00
|
|
|
provider: cloudprovider.AWS,
|
|
|
|
fileList: []string{
|
|
|
|
"main.tf",
|
|
|
|
"variables.tf",
|
|
|
|
"outputs.tf",
|
|
|
|
"modules",
|
|
|
|
},
|
|
|
|
testAlreadyUnpacked: true,
|
|
|
|
},
|
2022-09-26 09:52:31 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
for name, tc := range testCases {
|
|
|
|
t.Run(name, func(t *testing.T) {
|
|
|
|
assert := assert.New(t)
|
|
|
|
require := require.New(t)
|
|
|
|
|
|
|
|
file := file.NewHandler(afero.NewMemMapFs())
|
|
|
|
|
2022-12-07 05:48:54 -05:00
|
|
|
path := path.Join(tc.pathBase, strings.ToLower(tc.provider.String()))
|
|
|
|
err := prepareWorkspace(path, file, constants.TerraformWorkingDir)
|
|
|
|
|
2022-09-26 09:52:31 -04:00
|
|
|
require.NoError(err)
|
2023-05-22 07:31:20 -04:00
|
|
|
checkFiles(t, file, func(err error) { assert.NoError(err) }, constants.TerraformWorkingDir, tc.fileList)
|
2022-09-26 09:52:31 -04:00
|
|
|
|
2022-11-14 13:15:10 -05:00
|
|
|
if tc.testAlreadyUnpacked {
|
|
|
|
// Let's try the same again and check if we don't get a "file already exists" error.
|
|
|
|
require.NoError(file.Remove(filepath.Join(constants.TerraformWorkingDir, "variables.tf")))
|
2022-12-07 05:48:54 -05:00
|
|
|
err := prepareWorkspace(path, file, constants.TerraformWorkingDir)
|
2022-11-14 13:15:10 -05:00
|
|
|
assert.NoError(err)
|
2023-05-22 07:31:20 -04:00
|
|
|
checkFiles(t, file, func(err error) { assert.NoError(err) }, constants.TerraformWorkingDir, tc.fileList)
|
2022-11-14 13:15:10 -05:00
|
|
|
}
|
|
|
|
|
2022-11-14 12:18:58 -05:00
|
|
|
err = cleanUpWorkspace(file, constants.TerraformWorkingDir)
|
2022-09-26 09:52:31 -04:00
|
|
|
require.NoError(err)
|
|
|
|
|
2023-05-22 07:31:20 -04:00
|
|
|
checkFiles(t, file, func(err error) { assert.ErrorIs(err, fs.ErrNotExist) }, constants.TerraformWorkingDir, tc.fileList)
|
2022-09-26 09:52:31 -04:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-22 07:31:20 -04:00
|
|
|
func TestPrepareUpgradeWorkspace(t *testing.T) {
|
|
|
|
testCases := map[string]struct {
|
|
|
|
pathBase string
|
|
|
|
provider cloudprovider.Provider
|
|
|
|
oldWorkingDir string
|
|
|
|
newWorkingDir string
|
2023-06-21 03:22:32 -04:00
|
|
|
backupDir string
|
2023-05-22 07:31:20 -04:00
|
|
|
oldWorkspaceFiles []string
|
|
|
|
newWorkspaceFiles []string
|
|
|
|
expectedFiles []string
|
|
|
|
testAlreadyUnpacked bool
|
|
|
|
wantErr bool
|
|
|
|
}{
|
|
|
|
"works": {
|
|
|
|
pathBase: "terraform",
|
|
|
|
provider: cloudprovider.AWS,
|
|
|
|
oldWorkingDir: "old",
|
|
|
|
newWorkingDir: "new",
|
2023-06-21 03:22:32 -04:00
|
|
|
backupDir: "backup",
|
2023-05-22 07:31:20 -04:00
|
|
|
oldWorkspaceFiles: []string{"terraform.tfstate"},
|
|
|
|
expectedFiles: []string{
|
|
|
|
"main.tf",
|
|
|
|
"variables.tf",
|
|
|
|
"outputs.tf",
|
|
|
|
"modules",
|
|
|
|
"terraform.tfstate",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"state file does not exist": {
|
|
|
|
pathBase: "terraform",
|
|
|
|
provider: cloudprovider.AWS,
|
|
|
|
oldWorkingDir: "old",
|
|
|
|
newWorkingDir: "new",
|
2023-06-21 03:22:32 -04:00
|
|
|
backupDir: "backup",
|
2023-05-22 07:31:20 -04:00
|
|
|
oldWorkspaceFiles: []string{},
|
|
|
|
expectedFiles: []string{},
|
|
|
|
wantErr: true,
|
|
|
|
},
|
|
|
|
"terraform files already exist in new dir": {
|
|
|
|
pathBase: "terraform",
|
|
|
|
provider: cloudprovider.AWS,
|
|
|
|
oldWorkingDir: "old",
|
|
|
|
newWorkingDir: "new",
|
2023-06-21 03:22:32 -04:00
|
|
|
backupDir: "backup",
|
2023-05-22 07:31:20 -04:00
|
|
|
oldWorkspaceFiles: []string{"terraform.tfstate"},
|
|
|
|
newWorkspaceFiles: []string{"main.tf"},
|
|
|
|
wantErr: true,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for name, tc := range testCases {
|
|
|
|
t.Run(name, func(t *testing.T) {
|
|
|
|
require := require.New(t)
|
|
|
|
assert := assert.New(t)
|
|
|
|
|
|
|
|
file := file.NewHandler(afero.NewMemMapFs())
|
|
|
|
|
|
|
|
path := path.Join(tc.pathBase, strings.ToLower(tc.provider.String()))
|
|
|
|
|
|
|
|
createFiles(t, file, tc.oldWorkspaceFiles, tc.oldWorkingDir)
|
|
|
|
createFiles(t, file, tc.newWorkspaceFiles, tc.newWorkingDir)
|
|
|
|
|
2023-06-21 03:22:32 -04:00
|
|
|
err := prepareUpgradeWorkspace(path, file, tc.oldWorkingDir, tc.newWorkingDir, tc.backupDir)
|
2023-05-22 07:31:20 -04:00
|
|
|
|
|
|
|
if tc.wantErr {
|
|
|
|
require.Error(err)
|
|
|
|
} else {
|
|
|
|
require.NoError(err)
|
|
|
|
}
|
|
|
|
checkFiles(t, file, func(err error) { assert.NoError(err) }, tc.newWorkingDir, tc.expectedFiles)
|
|
|
|
checkFiles(t, file, func(err error) { assert.NoError(err) },
|
2023-06-21 03:22:32 -04:00
|
|
|
tc.backupDir,
|
2023-05-22 07:31:20 -04:00
|
|
|
tc.oldWorkspaceFiles,
|
|
|
|
)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func checkFiles(t *testing.T, fileHandler file.Handler, assertion func(error), dir string, files []string) {
|
2022-09-26 09:52:31 -04:00
|
|
|
t.Helper()
|
|
|
|
for _, f := range files {
|
2023-05-22 07:31:20 -04:00
|
|
|
path := filepath.Join(dir, f)
|
|
|
|
_, err := fileHandler.Stat(path)
|
2022-09-26 09:52:31 -04:00
|
|
|
assertion(err)
|
|
|
|
}
|
|
|
|
}
|
2023-05-22 07:31:20 -04:00
|
|
|
|
|
|
|
func createFiles(t *testing.T, fileHandler file.Handler, fileList []string, targetDir string) {
|
|
|
|
t.Helper()
|
|
|
|
require := require.New(t)
|
|
|
|
|
|
|
|
for _, f := range fileList {
|
|
|
|
path := filepath.Join(targetDir, f)
|
|
|
|
err := fileHandler.Write(path, []byte("1234"), file.OptOverwrite, file.OptMkdirAll)
|
|
|
|
require.NoError(err)
|
|
|
|
}
|
|
|
|
}
|