mirror of
https://github.com/edgelesssys/constellation.git
synced 2024-12-27 00:19:36 -05:00
95cf4bdf21
* perform upgrades in-place in terraform workspace Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * update buildfiles Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * add iam upgrade apply test Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * update buildfiles Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * fix linter Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * make config fetcher stubbable Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * change workspace restoring behaviour Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * allow overwriting existing Terraform files Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * allow overwrites of TF variables Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * fix iam upgrade apply Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * fix embed directive Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * make loader test less brittle Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * pass upgrade ID to user Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * naming nit Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * use upgradeDir Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * tidy Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> --------- Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>
82 lines
2.3 KiB
Go
82 lines
2.3 KiB
Go
/*
|
|
Copyright (c) Edgeless Systems GmbH
|
|
|
|
SPDX-License-Identifier: AGPL-3.0-only
|
|
*/
|
|
|
|
package cloudcmd
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
|
|
"github.com/edgelesssys/constellation/v2/cli/internal/terraform"
|
|
"github.com/edgelesssys/constellation/v2/internal/file"
|
|
)
|
|
|
|
// planUpgrade prepares a workspace and plans the possible Terraform migrations.
|
|
// In case of possible migrations, the diff is written to outWriter and this function returns true.
|
|
func planUpgrade(
|
|
ctx context.Context, tfClient tfUpgradePlanner, fileHandler file.Handler,
|
|
outWriter io.Writer, logLevel terraform.LogLevel, vars terraform.Variables,
|
|
templateDir, backupDir string,
|
|
) (bool, error) {
|
|
if err := ensureFileNotExist(fileHandler, backupDir); err != nil {
|
|
return false, fmt.Errorf("backup directory %s already exists: %w", backupDir, err)
|
|
}
|
|
|
|
// Backup the old Terraform workspace and move the embedded Terraform files into the workspace.
|
|
err := tfClient.PrepareUpgradeWorkspace(
|
|
templateDir,
|
|
backupDir,
|
|
vars,
|
|
)
|
|
if err != nil {
|
|
return false, fmt.Errorf("preparing terraform workspace: %w", err)
|
|
}
|
|
|
|
hasDiff, err := tfClient.Plan(ctx, logLevel)
|
|
if err != nil {
|
|
return false, fmt.Errorf("terraform plan: %w", err)
|
|
}
|
|
|
|
if hasDiff {
|
|
if err := tfClient.ShowPlan(ctx, logLevel, outWriter); err != nil {
|
|
return false, fmt.Errorf("terraform show plan: %w", err)
|
|
}
|
|
}
|
|
|
|
return hasDiff, nil
|
|
}
|
|
|
|
// restoreBackup replaces the existing Terraform workspace with the backup.
|
|
func restoreBackup(fileHandler file.Handler, workingDir, backupDir string) error {
|
|
if err := fileHandler.RemoveAll(workingDir); err != nil {
|
|
return fmt.Errorf("removing existing workspace: %w", err)
|
|
}
|
|
if err := fileHandler.CopyDir(
|
|
backupDir,
|
|
workingDir,
|
|
); err != nil {
|
|
return fmt.Errorf("replacing terraform workspace with backup: %w", err)
|
|
}
|
|
|
|
if err := fileHandler.RemoveAll(backupDir); err != nil {
|
|
return fmt.Errorf("removing backup directory: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// ensureFileNotExist checks if a single file or directory does not exist, returning an error if it does.
|
|
func ensureFileNotExist(fileHandler file.Handler, fileName string) error {
|
|
if _, err := fileHandler.Stat(fileName); err != nil {
|
|
if !os.IsNotExist(err) {
|
|
return fmt.Errorf("checking %q: %w", fileName, err)
|
|
}
|
|
return nil
|
|
}
|
|
return fmt.Errorf("%q already exists", fileName)
|
|
}
|