cli: add --workspace flag to set base directory for Constellation workspace (#2148)

* Remove `--config` and `--master-secret` falgs

* Add `--workspace` flag

* In CLI, only work on files with paths created from `cli/internal/cmd`

* Properly print values for GCP on IAM create when not directly updating the config

---------

Signed-off-by: Daniel Weiße <dw@edgeless.systems>
This commit is contained in:
Daniel Weiße 2023-08-04 13:53:51 +02:00 committed by GitHub
parent ec33530c38
commit d1ace13713
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
57 changed files with 966 additions and 1145 deletions

View file

@ -14,7 +14,6 @@ import (
"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"
@ -104,25 +103,26 @@ func TestPrepareWorkspace(t *testing.T) {
require := require.New(t)
file := file.NewHandler(afero.NewMemMapFs())
testWorkspace := "unittest"
path := path.Join(tc.pathBase, strings.ToLower(tc.provider.String()))
err := prepareWorkspace(path, file, constants.TerraformWorkingDir)
err := prepareWorkspace(path, file, testWorkspace)
require.NoError(err)
checkFiles(t, file, func(err error) { assert.NoError(err) }, constants.TerraformWorkingDir, tc.fileList)
checkFiles(t, file, func(err error) { assert.NoError(err) }, testWorkspace, tc.fileList)
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")))
err := prepareWorkspace(path, file, constants.TerraformWorkingDir)
require.NoError(file.Remove(filepath.Join(testWorkspace, "variables.tf")))
err := prepareWorkspace(path, file, testWorkspace)
assert.NoError(err)
checkFiles(t, file, func(err error) { assert.NoError(err) }, constants.TerraformWorkingDir, tc.fileList)
checkFiles(t, file, func(err error) { assert.NoError(err) }, testWorkspace, tc.fileList)
}
err = cleanUpWorkspace(file, constants.TerraformWorkingDir)
err = cleanUpWorkspace(file, testWorkspace)
require.NoError(err)
checkFiles(t, file, func(err error) { assert.ErrorIs(err, fs.ErrNotExist) }, constants.TerraformWorkingDir, tc.fileList)
checkFiles(t, file, func(err error) { assert.ErrorIs(err, fs.ErrNotExist) }, testWorkspace, tc.fileList)
})
}
}

View file

@ -38,6 +38,9 @@ import (
const (
tfVersion = ">= 1.4.6"
terraformVarsFile = "terraform.tfvars"
// terraformUpgradePlanFile is the file name of the zipfile created by Terraform plan for Constellation upgrades.
terraformUpgradePlanFile = "plan.zip"
)
// ErrTerraformWorkspaceExistsWithDifferentVariables is returned when existing Terraform files differ from the version the CLI wants to extract.
@ -438,9 +441,10 @@ func (c *Client) ApplyIAMConfig(ctx context.Context, provider cloudprovider.Prov
return c.ShowIAM(ctx, provider)
}
// Plan determines the diff that will be applied by Terraform. The plan output is written to the planFile.
// Plan determines the diff that will be applied by Terraform.
// The plan output is written to the Terraform working directory.
// If there is a diff, the returned bool is true. Otherwise, it is false.
func (c *Client) Plan(ctx context.Context, logLevel LogLevel, planFile string) (bool, error) {
func (c *Client) Plan(ctx context.Context, logLevel LogLevel) (bool, error) {
if err := c.setLogLevel(logLevel); err != nil {
return false, fmt.Errorf("set terraform log level %s: %w", logLevel.String(), err)
}
@ -454,18 +458,19 @@ func (c *Client) Plan(ctx context.Context, logLevel LogLevel, planFile string) (
}
opts := []tfexec.PlanOption{
tfexec.Out(planFile),
tfexec.Out(terraformUpgradePlanFile),
}
return c.tf.Plan(ctx, opts...)
}
// ShowPlan formats the diff in planFilePath and writes it to the specified output.
func (c *Client) ShowPlan(ctx context.Context, logLevel LogLevel, planFilePath string, output io.Writer) error {
// ShowPlan formats the diff of a plan file in the Terraform working directory,
// and writes it to the specified output.
func (c *Client) ShowPlan(ctx context.Context, logLevel LogLevel, output io.Writer) error {
if err := c.setLogLevel(logLevel); err != nil {
return fmt.Errorf("set terraform log level %s: %w", logLevel.String(), err)
}
planResult, err := c.tf.ShowPlanFileRaw(ctx, planFilePath)
planResult, err := c.tf.ShowPlanFileRaw(ctx, terraformUpgradePlanFile)
if err != nil {
return fmt.Errorf("terraform show plan: %w", err)
}
@ -575,6 +580,9 @@ func (c *Client) setLogLevel(logLevel LogLevel) error {
if err := c.tf.SetLog(logLevel.String()); err != nil {
return fmt.Errorf("set log level %s: %w", logLevel.String(), err)
}
// Terraform writes its log to the working directory.
// => Set the log path to the parent directory to have it in the user's working directory.
if err := c.tf.SetLogPath(filepath.Join("..", constants.TerraformLogFile)); err != nil {
return fmt.Errorf("set log path: %w", err)
}

View file

@ -92,7 +92,7 @@ func TestPrepareCluster(t *testing.T) {
c := &Client{
tf: &stubTerraform{},
file: file.NewHandler(tc.fs),
workingDir: constants.TerraformWorkingDir,
workingDir: "unittest",
}
path := path.Join(tc.pathBase, strings.ToLower(tc.provider.String()))
@ -445,7 +445,7 @@ func TestCreateCluster(t *testing.T) {
c := &Client{
tf: tc.tf,
file: file.NewHandler(tc.fs),
workingDir: constants.TerraformWorkingDir,
workingDir: "unittest",
}
path := path.Join(tc.pathBase, strings.ToLower(tc.provider.String()))
@ -835,7 +835,7 @@ func TestCleanupWorkspace(t *testing.T) {
c := &Client{
file: file,
tf: &stubTerraform{},
workingDir: constants.TerraformWorkingDir,
workingDir: "unittest",
}
err := c.CleanUpWorkspace()
@ -1019,7 +1019,7 @@ func TestPlan(t *testing.T) {
workingDir: tc.pathBase,
}
_, err := c.Plan(context.Background(), LogLevelDebug, constants.TerraformUpgradePlanFile)
_, err := c.Plan(context.Background(), LogLevelDebug)
if tc.wantErr {
require.Error(err)
} else {
@ -1078,7 +1078,7 @@ func TestShowPlan(t *testing.T) {
workingDir: tc.pathBase,
}
err := c.ShowPlan(context.Background(), LogLevelDebug, "", bytes.NewBuffer(nil))
err := c.ShowPlan(context.Background(), LogLevelDebug, bytes.NewBuffer(nil))
if tc.wantErr {
require.Error(err)
} else {