mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-01-22 21:31:14 -05:00
cli: move helm and terraform out of kubernetes package (#2222)
Signed-off-by: Daniel Weiße <dw@edgeless.systems>
This commit is contained in:
parent
f270e91724
commit
ed0bfd9d41
@ -8,8 +8,6 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/terraform"
|
"github.com/edgelesssys/constellation/v2/cli/internal/terraform"
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/upgrade"
|
"github.com/edgelesssys/constellation/v2/cli/internal/upgrade"
|
||||||
@ -18,7 +16,6 @@ import (
|
|||||||
"github.com/edgelesssys/constellation/v2/internal/config"
|
"github.com/edgelesssys/constellation/v2/internal/config"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/constants"
|
"github.com/edgelesssys/constellation/v2/internal/constants"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/file"
|
"github.com/edgelesssys/constellation/v2/internal/file"
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/spf13/afero"
|
"github.com/spf13/afero"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
@ -70,7 +67,8 @@ func runIAMUpgradeApply(cmd *cobra.Command, _ []string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
upgradeID := "iam-" + time.Now().Format("20060102150405") + "-" + strings.Split(uuid.New().String(), "-")[0]
|
|
||||||
|
upgradeID := generateUpgradeID(upgradeCmdKindIAM)
|
||||||
iamMigrateCmd, err := upgrade.NewIAMMigrateCmd(cmd.Context(), constants.TerraformIAMWorkingDir, constants.UpgradeDir, upgradeID, conf.GetProvider(), terraform.LogLevelDebug)
|
iamMigrateCmd, err := upgrade.NewIAMMigrateCmd(cmd.Context(), constants.TerraformIAMWorkingDir, constants.UpgradeDir, upgradeID, conf.GetProvider(), terraform.LogLevelDebug)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("setting up IAM migration command: %w", err)
|
return fmt.Errorf("setting up IAM migration command: %w", err)
|
||||||
@ -86,10 +84,10 @@ func runIAMUpgradeApply(cmd *cobra.Command, _ []string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = migrator.applyMigration(cmd, constants.UpgradeDir, file.NewHandler(afero.NewOsFs()), iamMigrateCmd, yes)
|
if err := migrator.applyMigration(cmd, constants.UpgradeDir, file.NewHandler(afero.NewOsFs()), iamMigrateCmd, yes); err != nil {
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("applying IAM migration: %w", err)
|
return fmt.Errorf("applying IAM migration: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Println("IAM profile successfully applied.")
|
cmd.Println("IAM profile successfully applied.")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,10 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -23,3 +27,31 @@ func NewUpgradeCmd() *cobra.Command {
|
|||||||
cmd.AddCommand(newUpgradeApplyCmd())
|
cmd.AddCommand(newUpgradeApplyCmd())
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// upgradeCmdKind is the kind of the upgrade command (check, apply).
|
||||||
|
type upgradeCmdKind int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// upgradeCmdKindCheck corresponds to the upgrade check command.
|
||||||
|
upgradeCmdKindCheck upgradeCmdKind = iota
|
||||||
|
// upgradeCmdKindApply corresponds to the upgrade apply command.
|
||||||
|
upgradeCmdKindApply
|
||||||
|
// upgradeCmdKindIAM corresponds to the IAM upgrade command.
|
||||||
|
upgradeCmdKindIAM
|
||||||
|
)
|
||||||
|
|
||||||
|
func generateUpgradeID(kind upgradeCmdKind) string {
|
||||||
|
upgradeID := time.Now().Format("20060102150405") + "-" + strings.Split(uuid.New().String(), "-")[0]
|
||||||
|
switch kind {
|
||||||
|
case upgradeCmdKindCheck:
|
||||||
|
// When performing an upgrade check, the upgrade directory will only be used temporarily to store the
|
||||||
|
// Terraform state. The directory is deleted after the check is finished.
|
||||||
|
// Therefore, add a tmp-suffix to the upgrade ID to indicate that the directory will be cleared after the check.
|
||||||
|
upgradeID = "upgrade-" + upgradeID + "-tmp"
|
||||||
|
case upgradeCmdKindApply:
|
||||||
|
upgradeID = "upgrade-" + upgradeID
|
||||||
|
case upgradeCmdKindIAM:
|
||||||
|
upgradeID = "iam-" + upgradeID
|
||||||
|
}
|
||||||
|
return upgradeID
|
||||||
|
}
|
||||||
|
@ -28,6 +28,7 @@ import (
|
|||||||
"github.com/edgelesssys/constellation/v2/internal/constants"
|
"github.com/edgelesssys/constellation/v2/internal/constants"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/file"
|
"github.com/edgelesssys/constellation/v2/internal/file"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/kms/uri"
|
"github.com/edgelesssys/constellation/v2/internal/kms/uri"
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/kubernetes/kubectl"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versions"
|
"github.com/edgelesssys/constellation/v2/internal/versions"
|
||||||
"github.com/rogpeppe/go-internal/diff"
|
"github.com/rogpeppe/go-internal/diff"
|
||||||
"github.com/spf13/afero"
|
"github.com/spf13/afero"
|
||||||
@ -64,29 +65,50 @@ func runUpgradeApply(cmd *cobra.Command, _ []string) error {
|
|||||||
return fmt.Errorf("creating logger: %w", err)
|
return fmt.Errorf("creating logger: %w", err)
|
||||||
}
|
}
|
||||||
defer log.Sync()
|
defer log.Sync()
|
||||||
fileHandler := file.NewHandler(afero.NewOsFs())
|
|
||||||
|
|
||||||
upgrader, err := kubernetes.NewUpgrader(
|
fileHandler := file.NewHandler(afero.NewOsFs())
|
||||||
cmd.Context(), cmd.OutOrStdout(),
|
upgradeID := generateUpgradeID(upgradeCmdKindApply)
|
||||||
constants.UpgradeDir, constants.AdminConfFilename,
|
|
||||||
fileHandler, log, kubernetes.UpgradeCmdKindApply,
|
kubeUpgrader, err := kubernetes.NewUpgrader(cmd.OutOrStdout(), constants.AdminConfFilename, log)
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
helmUpgrader, err := helm.NewUpgradeClient(kubectl.New(), constants.UpgradeDir, constants.AdminConfFilename, constants.HelmNamespace, log)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("setting up helm client: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
configFetcher := attestationconfigapi.NewFetcher()
|
configFetcher := attestationconfigapi.NewFetcher()
|
||||||
tfClient, err := terraform.New(cmd.Context(), constants.TerraformWorkingDir)
|
|
||||||
|
// Set up two Terraform clients. They need to be configured with different workspaces
|
||||||
|
// One for upgrading existing resources
|
||||||
|
tfUpgrader, err := terraform.New(cmd.Context(), filepath.Join(constants.UpgradeDir, upgradeID, constants.TerraformUpgradeWorkingDir))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("setting up terraform client: %w", err)
|
||||||
|
}
|
||||||
|
// And one for showing existing resources
|
||||||
|
tfShower, err := terraform.New(cmd.Context(), constants.TerraformWorkingDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("setting up terraform client: %w", err)
|
return fmt.Errorf("setting up terraform client: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
applyCmd := upgradeApplyCmd{upgrader: upgrader, log: log, configFetcher: configFetcher, clusterShower: tfClient, fileHandler: fileHandler}
|
applyCmd := upgradeApplyCmd{
|
||||||
|
helmUpgrader: helmUpgrader,
|
||||||
|
kubeUpgrader: kubeUpgrader,
|
||||||
|
terraformUpgrader: upgrade.NewTerraformUpgrader(tfUpgrader, cmd.OutOrStdout(), fileHandler, upgradeID),
|
||||||
|
configFetcher: configFetcher,
|
||||||
|
clusterShower: tfShower,
|
||||||
|
fileHandler: fileHandler,
|
||||||
|
log: log,
|
||||||
|
}
|
||||||
return applyCmd.upgradeApply(cmd)
|
return applyCmd.upgradeApply(cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
type upgradeApplyCmd struct {
|
type upgradeApplyCmd struct {
|
||||||
upgrader cloudUpgrader
|
helmUpgrader helmUpgrader
|
||||||
|
kubeUpgrader kubernetesUpgrader
|
||||||
|
terraformUpgrader terraformUpgrader
|
||||||
configFetcher attestationconfigapi.Fetcher
|
configFetcher attestationconfigapi.Fetcher
|
||||||
clusterShower clusterShower
|
clusterShower clusterShower
|
||||||
fileHandler file.Handler
|
fileHandler file.Handler
|
||||||
@ -131,7 +153,7 @@ func (u *upgradeApplyCmd) upgradeApply(cmd *cobra.Command) error {
|
|||||||
}
|
}
|
||||||
if idFile.MeasurementSalt == nil {
|
if idFile.MeasurementSalt == nil {
|
||||||
// TODO(elchead): remove after 2.10, since 2.9 does not yet save it in the idfile
|
// TODO(elchead): remove after 2.10, since 2.9 does not yet save it in the idfile
|
||||||
measurementSalt, err := u.upgrader.GetMeasurementSalt(cmd.Context())
|
measurementSalt, err := u.kubeUpgrader.GetMeasurementSalt(cmd.Context())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("getting join-config: %w", err)
|
return fmt.Errorf("getting join-config: %w", err)
|
||||||
}
|
}
|
||||||
@ -161,7 +183,7 @@ func (u *upgradeApplyCmd) upgradeApply(cmd *cobra.Command) error {
|
|||||||
// - fallback endpoint
|
// - fallback endpoint
|
||||||
// - custom (user-provided) endpoint
|
// - custom (user-provided) endpoint
|
||||||
sans := append([]string{idFile.IP, conf.CustomEndpoint}, idFile.APIServerCertSANs...)
|
sans := append([]string{idFile.IP, conf.CustomEndpoint}, idFile.APIServerCertSANs...)
|
||||||
if err := u.upgrader.ExtendClusterConfigCertSANs(cmd.Context(), sans); err != nil {
|
if err := u.kubeUpgrader.ExtendClusterConfigCertSANs(cmd.Context(), sans); err != nil {
|
||||||
return fmt.Errorf("extending cert SANs: %w", err)
|
return fmt.Errorf("extending cert SANs: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,7 +199,7 @@ func (u *upgradeApplyCmd) upgradeApply(cmd *cobra.Command) error {
|
|||||||
return fmt.Errorf("upgrading services: %w", err)
|
return fmt.Errorf("upgrading services: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = u.upgrader.UpgradeNodeVersion(cmd.Context(), conf, flags.force)
|
err = u.kubeUpgrader.UpgradeNodeVersion(cmd.Context(), conf, flags.force)
|
||||||
switch {
|
switch {
|
||||||
case errors.Is(err, kubernetes.ErrInProgress):
|
case errors.Is(err, kubernetes.ErrInProgress):
|
||||||
cmd.PrintErrln("Skipping image and Kubernetes upgrades. Another upgrade is in progress.")
|
cmd.PrintErrln("Skipping image and Kubernetes upgrades. Another upgrade is in progress.")
|
||||||
@ -214,7 +236,7 @@ func (u *upgradeApplyCmd) migrateTerraform(
|
|||||||
) (res terraform.ApplyOutput, err error) {
|
) (res terraform.ApplyOutput, err error) {
|
||||||
u.log.Debugf("Planning Terraform migrations")
|
u.log.Debugf("Planning Terraform migrations")
|
||||||
|
|
||||||
if err := u.upgrader.CheckTerraformMigrations(constants.UpgradeDir); err != nil {
|
if err := u.terraformUpgrader.CheckTerraformMigrations(constants.UpgradeDir); err != nil {
|
||||||
return res, fmt.Errorf("checking workspace: %w", err)
|
return res, fmt.Errorf("checking workspace: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,7 +264,7 @@ func (u *upgradeApplyCmd) migrateTerraform(
|
|||||||
// u.upgrader.AddManualStateMigration(migration)
|
// u.upgrader.AddManualStateMigration(migration)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
hasDiff, err := u.upgrader.PlanTerraformMigrations(cmd.Context(), opts)
|
hasDiff, err := u.terraformUpgrader.PlanTerraformMigrations(cmd.Context(), opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, fmt.Errorf("planning terraform migrations: %w", err)
|
return res, fmt.Errorf("planning terraform migrations: %w", err)
|
||||||
}
|
}
|
||||||
@ -257,14 +279,14 @@ func (u *upgradeApplyCmd) migrateTerraform(
|
|||||||
}
|
}
|
||||||
if !ok {
|
if !ok {
|
||||||
cmd.Println("Aborting upgrade.")
|
cmd.Println("Aborting upgrade.")
|
||||||
if err := u.upgrader.CleanUpTerraformMigrations(constants.UpgradeDir); err != nil {
|
if err := u.terraformUpgrader.CleanUpTerraformMigrations(constants.UpgradeDir); err != nil {
|
||||||
return res, fmt.Errorf("cleaning up workspace: %w", err)
|
return res, fmt.Errorf("cleaning up workspace: %w", err)
|
||||||
}
|
}
|
||||||
return res, fmt.Errorf("aborted by user")
|
return res, fmt.Errorf("aborted by user")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
u.log.Debugf("Applying Terraform migrations")
|
u.log.Debugf("Applying Terraform migrations")
|
||||||
tfOutput, err := u.upgrader.ApplyTerraformMigrations(cmd.Context(), opts)
|
tfOutput, err := u.terraformUpgrader.ApplyTerraformMigrations(cmd.Context(), opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return tfOutput, fmt.Errorf("applying terraform migrations: %w", err)
|
return tfOutput, fmt.Errorf("applying terraform migrations: %w", err)
|
||||||
}
|
}
|
||||||
@ -277,7 +299,9 @@ func (u *upgradeApplyCmd) migrateTerraform(
|
|||||||
|
|
||||||
cmd.Printf("Terraform migrations applied successfully and output written to: %s\n"+
|
cmd.Printf("Terraform migrations applied successfully and output written to: %s\n"+
|
||||||
"A backup of the pre-upgrade state has been written to: %s\n",
|
"A backup of the pre-upgrade state has been written to: %s\n",
|
||||||
flags.pf.PrefixPath(constants.ClusterIDsFilename), flags.pf.PrefixPath(filepath.Join(opts.UpgradeWorkspace, u.upgrader.GetUpgradeID(), constants.TerraformUpgradeBackupDir)))
|
flags.pf.PrefixPath(constants.ClusterIDsFilename),
|
||||||
|
flags.pf.PrefixPath(filepath.Join(opts.UpgradeWorkspace, u.terraformUpgrader.UpgradeID(), constants.TerraformUpgradeBackupDir)),
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
u.log.Debugf("No Terraform diff detected")
|
u.log.Debugf("No Terraform diff detected")
|
||||||
}
|
}
|
||||||
@ -327,7 +351,7 @@ func validK8sVersion(cmd *cobra.Command, version string, yes bool) (validVersion
|
|||||||
// confirmIfUpgradeAttestConfigHasDiff checks if the locally configured measurements are different from the cluster's measurements.
|
// confirmIfUpgradeAttestConfigHasDiff checks if the locally configured measurements are different from the cluster's measurements.
|
||||||
// If so the function will ask the user to confirm (if --yes is not set).
|
// If so the function will ask the user to confirm (if --yes is not set).
|
||||||
func (u *upgradeApplyCmd) confirmIfUpgradeAttestConfigHasDiff(cmd *cobra.Command, newConfig config.AttestationCfg, flags upgradeApplyFlags) error {
|
func (u *upgradeApplyCmd) confirmIfUpgradeAttestConfigHasDiff(cmd *cobra.Command, newConfig config.AttestationCfg, flags upgradeApplyFlags) error {
|
||||||
clusterAttestationConfig, err := u.upgrader.GetClusterAttestationConfig(cmd.Context(), newConfig.GetVariant())
|
clusterAttestationConfig, err := u.kubeUpgrader.GetClusterAttestationConfig(cmd.Context(), newConfig.GetVariant())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("getting cluster attestation config: %w", err)
|
return fmt.Errorf("getting cluster attestation config: %w", err)
|
||||||
}
|
}
|
||||||
@ -357,10 +381,10 @@ func (u *upgradeApplyCmd) confirmIfUpgradeAttestConfigHasDiff(cmd *cobra.Command
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO(elchead): move this outside this function to remove the side effect.
|
// TODO(elchead): move this outside this function to remove the side effect.
|
||||||
if err := u.upgrader.BackupConfigMap(cmd.Context(), constants.JoinConfigMap); err != nil {
|
if err := u.kubeUpgrader.BackupConfigMap(cmd.Context(), constants.JoinConfigMap); err != nil {
|
||||||
return fmt.Errorf("backing up join-config: %w", err)
|
return fmt.Errorf("backing up join-config: %w", err)
|
||||||
}
|
}
|
||||||
if err := u.upgrader.UpdateAttestationConfig(cmd.Context(), newConfig); err != nil {
|
if err := u.kubeUpgrader.UpdateAttestationConfig(cmd.Context(), newConfig); err != nil {
|
||||||
return fmt.Errorf("updating attestation config: %w", err)
|
return fmt.Errorf("updating attestation config: %w", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -375,7 +399,11 @@ func (u *upgradeApplyCmd) handleServiceUpgrade(cmd *cobra.Command, conf *config.
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("getting service account URI: %w", err)
|
return fmt.Errorf("getting service account URI: %w", err)
|
||||||
}
|
}
|
||||||
err = u.upgrader.UpgradeHelmServices(cmd.Context(), conf, idFile, flags.upgradeTimeout, helm.DenyDestructive, flags.force, flags.conformance, flags.helmWaitMode, secret, serviceAccURI, validK8sVersion, tfOutput)
|
err = u.helmUpgrader.Upgrade(
|
||||||
|
cmd.Context(), conf, idFile,
|
||||||
|
flags.upgradeTimeout, helm.DenyDestructive, flags.force, u.terraformUpgrader.UpgradeID(),
|
||||||
|
flags.conformance, flags.helmWaitMode, secret, serviceAccURI, validK8sVersion, tfOutput,
|
||||||
|
)
|
||||||
if errors.Is(err, helm.ErrConfirmationMissing) {
|
if errors.Is(err, helm.ErrConfirmationMissing) {
|
||||||
if !flags.yes {
|
if !flags.yes {
|
||||||
cmd.PrintErrln("WARNING: Upgrading cert-manager will destroy all custom resources you have manually created that are based on the current version of cert-manager.")
|
cmd.PrintErrln("WARNING: Upgrading cert-manager will destroy all custom resources you have manually created that are based on the current version of cert-manager.")
|
||||||
@ -388,7 +416,11 @@ func (u *upgradeApplyCmd) handleServiceUpgrade(cmd *cobra.Command, conf *config.
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err = u.upgrader.UpgradeHelmServices(cmd.Context(), conf, idFile, flags.upgradeTimeout, helm.AllowDestructive, flags.force, flags.conformance, flags.helmWaitMode, secret, serviceAccURI, validK8sVersion, tfOutput)
|
err = u.helmUpgrader.Upgrade(
|
||||||
|
cmd.Context(), conf, idFile,
|
||||||
|
flags.upgradeTimeout, helm.AllowDestructive, flags.force, u.terraformUpgrader.UpgradeID(),
|
||||||
|
flags.conformance, flags.helmWaitMode, secret, serviceAccURI, validK8sVersion, tfOutput,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
@ -470,17 +502,27 @@ type upgradeApplyFlags struct {
|
|||||||
helmWaitMode helm.WaitMode
|
helmWaitMode helm.WaitMode
|
||||||
}
|
}
|
||||||
|
|
||||||
type cloudUpgrader interface {
|
type kubernetesUpgrader interface {
|
||||||
UpgradeNodeVersion(ctx context.Context, conf *config.Config, force bool) error
|
UpgradeNodeVersion(ctx context.Context, conf *config.Config, force bool) error
|
||||||
UpgradeHelmServices(ctx context.Context, config *config.Config, idFile clusterid.File, timeout time.Duration, allowDestructive bool, force bool, conformance bool, helmWaitMode helm.WaitMode, masterSecret uri.MasterSecret, serviceAccURI string, validK8sVersion versions.ValidK8sVersion, tfOutput terraform.ApplyOutput) error
|
|
||||||
ExtendClusterConfigCertSANs(ctx context.Context, alternativeNames []string) error
|
ExtendClusterConfigCertSANs(ctx context.Context, alternativeNames []string) error
|
||||||
GetClusterAttestationConfig(ctx context.Context, variant variant.Variant) (config.AttestationCfg, error)
|
GetClusterAttestationConfig(ctx context.Context, variant variant.Variant) (config.AttestationCfg, error)
|
||||||
UpdateAttestationConfig(ctx context.Context, newAttestConfig config.AttestationCfg) error
|
UpdateAttestationConfig(ctx context.Context, newAttestConfig config.AttestationCfg) error
|
||||||
GetMeasurementSalt(ctx context.Context) ([]byte, error)
|
GetMeasurementSalt(ctx context.Context) ([]byte, error)
|
||||||
|
BackupConfigMap(ctx context.Context, name string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type helmUpgrader interface {
|
||||||
|
Upgrade(
|
||||||
|
ctx context.Context, config *config.Config, idFile clusterid.File, timeout time.Duration,
|
||||||
|
allowDestructive, force bool, upgradeID string, conformance bool, helmWaitMode helm.WaitMode,
|
||||||
|
masterSecret uri.MasterSecret, serviceAccURI string, validK8sVersion versions.ValidK8sVersion, tfOutput terraform.ApplyOutput,
|
||||||
|
) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type terraformUpgrader interface {
|
||||||
PlanTerraformMigrations(ctx context.Context, opts upgrade.TerraformUpgradeOptions) (bool, error)
|
PlanTerraformMigrations(ctx context.Context, opts upgrade.TerraformUpgradeOptions) (bool, error)
|
||||||
ApplyTerraformMigrations(ctx context.Context, opts upgrade.TerraformUpgradeOptions) (terraform.ApplyOutput, error)
|
ApplyTerraformMigrations(ctx context.Context, opts upgrade.TerraformUpgradeOptions) (terraform.ApplyOutput, error)
|
||||||
CheckTerraformMigrations(upgradeWorkspace string) error
|
CheckTerraformMigrations(upgradeWorkspace string) error
|
||||||
CleanUpTerraformMigrations(upgradeWorkspace string) error
|
CleanUpTerraformMigrations(upgradeWorkspace string) error
|
||||||
GetUpgradeID() string
|
UpgradeID() string
|
||||||
BackupConfigMap(ctx context.Context, name string) error
|
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -32,87 +31,106 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestUpgradeApply(t *testing.T) {
|
func TestUpgradeApply(t *testing.T) {
|
||||||
someErr := errors.New("some error")
|
|
||||||
testCases := map[string]struct {
|
testCases := map[string]struct {
|
||||||
upgrader *stubUpgrader
|
helmUpgrader *stubHelmUpgrader
|
||||||
|
kubeUpgrader *stubKubernetesUpgrader
|
||||||
|
terraformUpgrader *stubTerraformUpgrader
|
||||||
wantErr bool
|
wantErr bool
|
||||||
yesFlag bool
|
yesFlag bool
|
||||||
dontWantJoinConfigBackup bool
|
dontWantJoinConfigBackup bool
|
||||||
stdin string
|
stdin string
|
||||||
}{
|
}{
|
||||||
"success": {
|
"success": {
|
||||||
upgrader: &stubUpgrader{currentConfig: config.DefaultForAzureSEVSNP()},
|
kubeUpgrader: &stubKubernetesUpgrader{currentConfig: config.DefaultForAzureSEVSNP()},
|
||||||
|
helmUpgrader: &stubHelmUpgrader{},
|
||||||
|
terraformUpgrader: &stubTerraformUpgrader{},
|
||||||
yesFlag: true,
|
yesFlag: true,
|
||||||
},
|
},
|
||||||
"nodeVersion some error": {
|
"nodeVersion some error": {
|
||||||
upgrader: &stubUpgrader{
|
kubeUpgrader: &stubKubernetesUpgrader{
|
||||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
currentConfig: config.DefaultForAzureSEVSNP(),
|
||||||
nodeVersionErr: someErr,
|
nodeVersionErr: assert.AnError,
|
||||||
},
|
},
|
||||||
|
helmUpgrader: &stubHelmUpgrader{},
|
||||||
|
terraformUpgrader: &stubTerraformUpgrader{},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
yesFlag: true,
|
yesFlag: true,
|
||||||
},
|
},
|
||||||
"nodeVersion in progress error": {
|
"nodeVersion in progress error": {
|
||||||
upgrader: &stubUpgrader{
|
kubeUpgrader: &stubKubernetesUpgrader{
|
||||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
currentConfig: config.DefaultForAzureSEVSNP(),
|
||||||
nodeVersionErr: kubernetes.ErrInProgress,
|
nodeVersionErr: kubernetes.ErrInProgress,
|
||||||
},
|
},
|
||||||
|
helmUpgrader: &stubHelmUpgrader{},
|
||||||
|
terraformUpgrader: &stubTerraformUpgrader{},
|
||||||
yesFlag: true,
|
yesFlag: true,
|
||||||
},
|
},
|
||||||
"helm other error": {
|
"helm other error": {
|
||||||
upgrader: &stubUpgrader{
|
kubeUpgrader: &stubKubernetesUpgrader{
|
||||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
currentConfig: config.DefaultForAzureSEVSNP(),
|
||||||
helmErr: someErr,
|
|
||||||
},
|
},
|
||||||
|
helmUpgrader: &stubHelmUpgrader{err: assert.AnError},
|
||||||
|
terraformUpgrader: &stubTerraformUpgrader{},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
yesFlag: true,
|
yesFlag: true,
|
||||||
},
|
},
|
||||||
"check terraform error": {
|
"check terraform error": {
|
||||||
upgrader: &stubUpgrader{
|
kubeUpgrader: &stubKubernetesUpgrader{
|
||||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
currentConfig: config.DefaultForAzureSEVSNP(),
|
||||||
checkTerraformErr: someErr,
|
|
||||||
},
|
},
|
||||||
|
helmUpgrader: &stubHelmUpgrader{},
|
||||||
|
terraformUpgrader: &stubTerraformUpgrader{checkTerraformErr: assert.AnError},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
yesFlag: true,
|
yesFlag: true,
|
||||||
},
|
},
|
||||||
"abort": {
|
"abort": {
|
||||||
upgrader: &stubUpgrader{
|
kubeUpgrader: &stubKubernetesUpgrader{
|
||||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
currentConfig: config.DefaultForAzureSEVSNP(),
|
||||||
terraformDiff: true,
|
|
||||||
},
|
},
|
||||||
|
helmUpgrader: &stubHelmUpgrader{},
|
||||||
|
terraformUpgrader: &stubTerraformUpgrader{terraformDiff: true},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
stdin: "no\n",
|
stdin: "no\n",
|
||||||
},
|
},
|
||||||
"clean terraform error": {
|
"clean terraform error": {
|
||||||
upgrader: &stubUpgrader{
|
kubeUpgrader: &stubKubernetesUpgrader{
|
||||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
currentConfig: config.DefaultForAzureSEVSNP(),
|
||||||
cleanTerraformErr: someErr,
|
},
|
||||||
|
helmUpgrader: &stubHelmUpgrader{},
|
||||||
|
terraformUpgrader: &stubTerraformUpgrader{
|
||||||
|
cleanTerraformErr: assert.AnError,
|
||||||
terraformDiff: true,
|
terraformDiff: true,
|
||||||
},
|
},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
stdin: "no\n",
|
stdin: "no\n",
|
||||||
},
|
},
|
||||||
"plan terraform error": {
|
"plan terraform error": {
|
||||||
upgrader: &stubUpgrader{
|
kubeUpgrader: &stubKubernetesUpgrader{
|
||||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
currentConfig: config.DefaultForAzureSEVSNP(),
|
||||||
planTerraformErr: someErr,
|
|
||||||
},
|
},
|
||||||
|
helmUpgrader: &stubHelmUpgrader{},
|
||||||
|
terraformUpgrader: &stubTerraformUpgrader{planTerraformErr: assert.AnError},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
yesFlag: true,
|
yesFlag: true,
|
||||||
},
|
},
|
||||||
"apply terraform error": {
|
"apply terraform error": {
|
||||||
upgrader: &stubUpgrader{
|
kubeUpgrader: &stubKubernetesUpgrader{
|
||||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
currentConfig: config.DefaultForAzureSEVSNP(),
|
||||||
applyTerraformErr: someErr,
|
},
|
||||||
|
helmUpgrader: &stubHelmUpgrader{},
|
||||||
|
terraformUpgrader: &stubTerraformUpgrader{
|
||||||
|
applyTerraformErr: assert.AnError,
|
||||||
terraformDiff: true,
|
terraformDiff: true,
|
||||||
},
|
},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
yesFlag: true,
|
yesFlag: true,
|
||||||
},
|
},
|
||||||
"do no backup join-config when remote attestation config is the same": {
|
"do no backup join-config when remote attestation config is the same": {
|
||||||
upgrader: &stubUpgrader{
|
kubeUpgrader: &stubKubernetesUpgrader{
|
||||||
currentConfig: fakeAzureAttestationConfigFromCluster(context.Background(), t, cloudprovider.Azure),
|
currentConfig: fakeAzureAttestationConfigFromCluster(context.Background(), t, cloudprovider.Azure),
|
||||||
},
|
},
|
||||||
|
helmUpgrader: &stubHelmUpgrader{},
|
||||||
|
terraformUpgrader: &stubTerraformUpgrader{},
|
||||||
yesFlag: true,
|
yesFlag: true,
|
||||||
dontWantJoinConfigBackup: true,
|
dontWantJoinConfigBackup: true,
|
||||||
},
|
},
|
||||||
@ -141,7 +159,15 @@ func TestUpgradeApply(t *testing.T) {
|
|||||||
require.NoError(handler.WriteJSON(constants.ClusterIDsFilename, clusterid.File{}))
|
require.NoError(handler.WriteJSON(constants.ClusterIDsFilename, clusterid.File{}))
|
||||||
require.NoError(handler.WriteJSON(constants.MasterSecretFilename, uri.MasterSecret{}))
|
require.NoError(handler.WriteJSON(constants.MasterSecretFilename, uri.MasterSecret{}))
|
||||||
|
|
||||||
upgrader := upgradeApplyCmd{upgrader: tc.upgrader, log: logger.NewTest(t), configFetcher: stubAttestationFetcher{}, clusterShower: &stubShowCluster{}, fileHandler: handler}
|
upgrader := upgradeApplyCmd{
|
||||||
|
kubeUpgrader: tc.kubeUpgrader,
|
||||||
|
helmUpgrader: tc.helmUpgrader,
|
||||||
|
terraformUpgrader: tc.terraformUpgrader,
|
||||||
|
log: logger.NewTest(t),
|
||||||
|
configFetcher: stubAttestationFetcher{},
|
||||||
|
clusterShower: &stubShowCluster{},
|
||||||
|
fileHandler: handler,
|
||||||
|
}
|
||||||
|
|
||||||
err := upgrader.upgradeApply(cmd)
|
err := upgrader.upgradeApply(cmd)
|
||||||
if tc.wantErr {
|
if tc.wantErr {
|
||||||
@ -149,70 +175,79 @@ func TestUpgradeApply(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
assert.Equal(!tc.dontWantJoinConfigBackup, tc.upgrader.backupWasCalled)
|
assert.Equal(!tc.dontWantJoinConfigBackup, tc.kubeUpgrader.backupWasCalled)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type stubUpgrader struct {
|
type stubHelmUpgrader struct {
|
||||||
currentConfig config.AttestationCfg
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u stubHelmUpgrader) Upgrade(
|
||||||
|
_ context.Context, _ *config.Config, _ clusterid.File, _ time.Duration, _, _ bool, _ string, _ bool,
|
||||||
|
_ helm.WaitMode, _ uri.MasterSecret, _ string, _ versions.ValidK8sVersion, _ terraform.ApplyOutput,
|
||||||
|
) error {
|
||||||
|
return u.err
|
||||||
|
}
|
||||||
|
|
||||||
|
type stubKubernetesUpgrader struct {
|
||||||
|
backupWasCalled bool
|
||||||
nodeVersionErr error
|
nodeVersionErr error
|
||||||
helmErr error
|
currentConfig config.AttestationCfg
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u stubKubernetesUpgrader) GetMeasurementSalt(_ context.Context) ([]byte, error) {
|
||||||
|
return []byte{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *stubKubernetesUpgrader) BackupConfigMap(_ context.Context, _ string) error {
|
||||||
|
u.backupWasCalled = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u stubKubernetesUpgrader) UpgradeNodeVersion(_ context.Context, _ *config.Config, _ bool) error {
|
||||||
|
return u.nodeVersionErr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u stubKubernetesUpgrader) UpdateAttestationConfig(_ context.Context, _ config.AttestationCfg) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u stubKubernetesUpgrader) GetClusterAttestationConfig(_ context.Context, _ variant.Variant) (config.AttestationCfg, error) {
|
||||||
|
return u.currentConfig, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u stubKubernetesUpgrader) ExtendClusterConfigCertSANs(_ context.Context, _ []string) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type stubTerraformUpgrader struct {
|
||||||
terraformDiff bool
|
terraformDiff bool
|
||||||
planTerraformErr error
|
planTerraformErr error
|
||||||
checkTerraformErr error
|
checkTerraformErr error
|
||||||
applyTerraformErr error
|
applyTerraformErr error
|
||||||
cleanTerraformErr error
|
cleanTerraformErr error
|
||||||
backupWasCalled bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u stubUpgrader) GetMeasurementSalt(_ context.Context) ([]byte, error) {
|
func (u stubTerraformUpgrader) CheckTerraformMigrations(_ string) error {
|
||||||
return []byte{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u stubUpgrader) GetUpgradeID() string {
|
|
||||||
return "test-upgrade"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *stubUpgrader) BackupConfigMap(_ context.Context, _ string) error {
|
|
||||||
u.backupWasCalled = true
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u stubUpgrader) UpgradeNodeVersion(_ context.Context, _ *config.Config, _ bool) error {
|
|
||||||
return u.nodeVersionErr
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u stubUpgrader) UpgradeHelmServices(_ context.Context, _ *config.Config, _ clusterid.File, _ time.Duration, _, _, _ bool, _ helm.WaitMode, _ uri.MasterSecret, _ string, _ versions.ValidK8sVersion, _ terraform.ApplyOutput) error {
|
|
||||||
return u.helmErr
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u stubUpgrader) UpdateAttestationConfig(_ context.Context, _ config.AttestationCfg) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u stubUpgrader) GetClusterAttestationConfig(_ context.Context, _ variant.Variant) (config.AttestationCfg, error) {
|
|
||||||
return u.currentConfig, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u stubUpgrader) CheckTerraformMigrations(_ string) error {
|
|
||||||
return u.checkTerraformErr
|
return u.checkTerraformErr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u stubUpgrader) CleanUpTerraformMigrations(_ string) error {
|
func (u stubTerraformUpgrader) CleanUpTerraformMigrations(_ string) error {
|
||||||
return u.cleanTerraformErr
|
return u.cleanTerraformErr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u stubUpgrader) PlanTerraformMigrations(context.Context, upgrade.TerraformUpgradeOptions) (bool, error) {
|
func (u stubTerraformUpgrader) PlanTerraformMigrations(context.Context, upgrade.TerraformUpgradeOptions) (bool, error) {
|
||||||
return u.terraformDiff, u.planTerraformErr
|
return u.terraformDiff, u.planTerraformErr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u stubUpgrader) ApplyTerraformMigrations(context.Context, upgrade.TerraformUpgradeOptions) (terraform.ApplyOutput, error) {
|
func (u stubTerraformUpgrader) ApplyTerraformMigrations(context.Context, upgrade.TerraformUpgradeOptions) (terraform.ApplyOutput, error) {
|
||||||
return terraform.ApplyOutput{}, u.applyTerraformErr
|
return terraform.ApplyOutput{}, u.applyTerraformErr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u stubUpgrader) ExtendClusterConfigCertSANs(_ context.Context, _ []string) error {
|
func (u stubTerraformUpgrader) UpgradeID() string {
|
||||||
return nil
|
return "test-upgrade"
|
||||||
}
|
}
|
||||||
|
|
||||||
func fakeAzureAttestationConfigFromCluster(ctx context.Context, t *testing.T, provider cloudprovider.Provider) config.AttestationCfg {
|
func fakeAzureAttestationConfigFromCluster(ctx context.Context, t *testing.T, provider cloudprovider.Provider) config.AttestationCfg {
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -71,11 +72,14 @@ func runUpgradeCheck(cmd *cobra.Command, _ []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fileHandler := file.NewHandler(afero.NewOsFs())
|
fileHandler := file.NewHandler(afero.NewOsFs())
|
||||||
checker, err := kubernetes.NewUpgrader(
|
upgradeID := generateUpgradeID(upgradeCmdKindCheck)
|
||||||
cmd.Context(), cmd.OutOrStdout(),
|
|
||||||
constants.UpgradeDir, constants.AdminConfFilename,
|
tfClient, err := terraform.New(cmd.Context(), filepath.Join(constants.UpgradeDir, upgradeID, constants.TerraformUpgradeWorkingDir))
|
||||||
fileHandler, log, kubernetes.UpgradeCmdKindCheck,
|
if err != nil {
|
||||||
)
|
return fmt.Errorf("setting up terraform client: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
kubeChecker, err := kubernetes.NewUpgrader(cmd.OutOrStdout(), constants.AdminConfFilename, log)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("setting up Kubernetes upgrader: %w", err)
|
return fmt.Errorf("setting up Kubernetes upgrader: %w", err)
|
||||||
}
|
}
|
||||||
@ -89,7 +93,7 @@ func runUpgradeCheck(cmd *cobra.Command, _ []string) error {
|
|||||||
canUpgradeCheck: featureset.CanUpgradeCheck,
|
canUpgradeCheck: featureset.CanUpgradeCheck,
|
||||||
collect: &versionCollector{
|
collect: &versionCollector{
|
||||||
writer: cmd.OutOrStderr(),
|
writer: cmd.OutOrStderr(),
|
||||||
checker: checker,
|
kubeChecker: kubeChecker,
|
||||||
verListFetcher: versionfetcher,
|
verListFetcher: versionfetcher,
|
||||||
fileHandler: fileHandler,
|
fileHandler: fileHandler,
|
||||||
client: http.DefaultClient,
|
client: http.DefaultClient,
|
||||||
@ -99,7 +103,7 @@ func runUpgradeCheck(cmd *cobra.Command, _ []string) error {
|
|||||||
log: log,
|
log: log,
|
||||||
versionsapi: versionfetcher,
|
versionsapi: versionfetcher,
|
||||||
},
|
},
|
||||||
checker: checker,
|
terraformChecker: upgrade.NewTerraformUpgrader(tfClient, cmd.OutOrStdout(), fileHandler, upgradeID),
|
||||||
log: log,
|
log: log,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,7 +149,7 @@ func parseUpgradeCheckFlags(cmd *cobra.Command) (upgradeCheckFlags, error) {
|
|||||||
type upgradeCheckCmd struct {
|
type upgradeCheckCmd struct {
|
||||||
canUpgradeCheck bool
|
canUpgradeCheck bool
|
||||||
collect collector
|
collect collector
|
||||||
checker upgradeChecker
|
terraformChecker terraformChecker
|
||||||
log debugLog
|
log debugLog
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,7 +216,7 @@ func (u *upgradeCheckCmd) upgradeCheck(cmd *cobra.Command, fileHandler file.Hand
|
|||||||
// u.upgrader.AddManualStateMigration(migration)
|
// u.upgrader.AddManualStateMigration(migration)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
if err := u.checker.CheckTerraformMigrations(constants.UpgradeDir); err != nil {
|
if err := u.terraformChecker.CheckTerraformMigrations(constants.UpgradeDir); err != nil {
|
||||||
return fmt.Errorf("checking workspace: %w", err)
|
return fmt.Errorf("checking workspace: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,12 +237,12 @@ func (u *upgradeCheckCmd) upgradeCheck(cmd *cobra.Command, fileHandler file.Hand
|
|||||||
cmd.Println("The following Terraform migrations are available with this CLI:")
|
cmd.Println("The following Terraform migrations are available with this CLI:")
|
||||||
|
|
||||||
// Check if there are any Terraform migrations
|
// Check if there are any Terraform migrations
|
||||||
hasDiff, err := u.checker.PlanTerraformMigrations(cmd.Context(), opts)
|
hasDiff, err := u.terraformChecker.PlanTerraformMigrations(cmd.Context(), opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("planning terraform migrations: %w", err)
|
return fmt.Errorf("planning terraform migrations: %w", err)
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := u.checker.CleanUpTerraformMigrations(constants.UpgradeDir); err != nil {
|
if err := u.terraformChecker.CleanUpTerraformMigrations(constants.UpgradeDir); err != nil {
|
||||||
u.log.Debugf("Failed to clean up Terraform migrations: %v", err)
|
u.log.Debugf("Failed to clean up Terraform migrations: %v", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
@ -323,7 +327,7 @@ type collector interface {
|
|||||||
|
|
||||||
type versionCollector struct {
|
type versionCollector struct {
|
||||||
writer io.Writer
|
writer io.Writer
|
||||||
checker upgradeChecker
|
kubeChecker kubernetesChecker
|
||||||
verListFetcher versionListFetcher
|
verListFetcher versionListFetcher
|
||||||
fileHandler file.Handler
|
fileHandler file.Handler
|
||||||
client *http.Client
|
client *http.Client
|
||||||
@ -382,12 +386,12 @@ func (v *versionCollector) currentVersions(ctx context.Context) (currentVersionI
|
|||||||
return currentVersionInfo{}, fmt.Errorf("getting service versions: %w", err)
|
return currentVersionInfo{}, fmt.Errorf("getting service versions: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
imageVersion, err := getCurrentImageVersion(ctx, v.checker)
|
imageVersion, err := getCurrentImageVersion(ctx, v.kubeChecker)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return currentVersionInfo{}, fmt.Errorf("getting image version: %w", err)
|
return currentVersionInfo{}, fmt.Errorf("getting image version: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
k8sVersion, err := getCurrentKubernetesVersion(ctx, v.checker)
|
k8sVersion, err := getCurrentKubernetesVersion(ctx, v.kubeChecker)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return currentVersionInfo{}, fmt.Errorf("getting Kubernetes version: %w", err)
|
return currentVersionInfo{}, fmt.Errorf("getting Kubernetes version: %w", err)
|
||||||
}
|
}
|
||||||
@ -588,7 +592,7 @@ func (v *versionUpgrade) writeConfig(conf *config.Config, fileHandler file.Handl
|
|||||||
|
|
||||||
// getCurrentImageVersion retrieves the semantic version of the image currently installed in the cluster.
|
// getCurrentImageVersion retrieves the semantic version of the image currently installed in the cluster.
|
||||||
// If the cluster is not using a release image, an error is returned.
|
// If the cluster is not using a release image, an error is returned.
|
||||||
func getCurrentImageVersion(ctx context.Context, checker upgradeChecker) (string, error) {
|
func getCurrentImageVersion(ctx context.Context, checker kubernetesChecker) (string, error) {
|
||||||
imageVersion, err := checker.CurrentImage(ctx)
|
imageVersion, err := checker.CurrentImage(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@ -602,7 +606,7 @@ func getCurrentImageVersion(ctx context.Context, checker upgradeChecker) (string
|
|||||||
}
|
}
|
||||||
|
|
||||||
// getCurrentKubernetesVersion retrieves the semantic version of Kubernetes currently installed in the cluster.
|
// getCurrentKubernetesVersion retrieves the semantic version of Kubernetes currently installed in the cluster.
|
||||||
func getCurrentKubernetesVersion(ctx context.Context, checker upgradeChecker) (string, error) {
|
func getCurrentKubernetesVersion(ctx context.Context, checker kubernetesChecker) (string, error) {
|
||||||
k8sVersion, err := checker.CurrentKubernetesVersion(ctx)
|
k8sVersion, err := checker.CurrentKubernetesVersion(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@ -745,9 +749,12 @@ type upgradeCheckFlags struct {
|
|||||||
terraformLogLevel terraform.LogLevel
|
terraformLogLevel terraform.LogLevel
|
||||||
}
|
}
|
||||||
|
|
||||||
type upgradeChecker interface {
|
type kubernetesChecker interface {
|
||||||
CurrentImage(ctx context.Context) (string, error)
|
CurrentImage(ctx context.Context) (string, error)
|
||||||
CurrentKubernetesVersion(ctx context.Context) (string, error)
|
CurrentKubernetesVersion(ctx context.Context) (string, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type terraformChecker interface {
|
||||||
PlanTerraformMigrations(ctx context.Context, opts upgrade.TerraformUpgradeOptions) (bool, error)
|
PlanTerraformMigrations(ctx context.Context, opts upgrade.TerraformUpgradeOptions) (bool, error)
|
||||||
CheckTerraformMigrations(upgradeWorkspace string) error
|
CheckTerraformMigrations(upgradeWorkspace string) error
|
||||||
CleanUpTerraformMigrations(upgradeWorkspace string) error
|
CleanUpTerraformMigrations(upgradeWorkspace string) error
|
||||||
|
@ -110,22 +110,22 @@ func TestBuildString(t *testing.T) {
|
|||||||
|
|
||||||
func TestGetCurrentImageVersion(t *testing.T) {
|
func TestGetCurrentImageVersion(t *testing.T) {
|
||||||
testCases := map[string]struct {
|
testCases := map[string]struct {
|
||||||
stubUpgradeChecker stubUpgradeChecker
|
stubKubernetesChecker stubKubernetesChecker
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
"valid version": {
|
"valid version": {
|
||||||
stubUpgradeChecker: stubUpgradeChecker{
|
stubKubernetesChecker: stubKubernetesChecker{
|
||||||
image: "v1.0.0",
|
image: "v1.0.0",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"invalid version": {
|
"invalid version": {
|
||||||
stubUpgradeChecker: stubUpgradeChecker{
|
stubKubernetesChecker: stubKubernetesChecker{
|
||||||
image: "invalid",
|
image: "invalid",
|
||||||
},
|
},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
},
|
},
|
||||||
"GetCurrentImage error": {
|
"GetCurrentImage error": {
|
||||||
stubUpgradeChecker: stubUpgradeChecker{
|
stubKubernetesChecker: stubKubernetesChecker{
|
||||||
err: errors.New("error"),
|
err: errors.New("error"),
|
||||||
},
|
},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
@ -136,7 +136,7 @@ func TestGetCurrentImageVersion(t *testing.T) {
|
|||||||
t.Run(name, func(t *testing.T) {
|
t.Run(name, func(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
version, err := getCurrentImageVersion(context.Background(), tc.stubUpgradeChecker)
|
version, err := getCurrentImageVersion(context.Background(), tc.stubKubernetesChecker)
|
||||||
if tc.wantErr {
|
if tc.wantErr {
|
||||||
assert.Error(err)
|
assert.Error(err)
|
||||||
return
|
return
|
||||||
@ -215,19 +215,19 @@ func TestUpgradeCheck(t *testing.T) {
|
|||||||
testCases := map[string]struct {
|
testCases := map[string]struct {
|
||||||
collector stubVersionCollector
|
collector stubVersionCollector
|
||||||
csp cloudprovider.Provider
|
csp cloudprovider.Provider
|
||||||
checker stubUpgradeChecker
|
checker stubTerraformChecker
|
||||||
cliVersion string
|
cliVersion string
|
||||||
wantError bool
|
wantError bool
|
||||||
}{
|
}{
|
||||||
"upgrades gcp": {
|
"upgrades gcp": {
|
||||||
collector: collector,
|
collector: collector,
|
||||||
checker: stubUpgradeChecker{},
|
checker: stubTerraformChecker{},
|
||||||
csp: cloudprovider.GCP,
|
csp: cloudprovider.GCP,
|
||||||
cliVersion: "v1.0.0",
|
cliVersion: "v1.0.0",
|
||||||
},
|
},
|
||||||
"terraform err": {
|
"terraform err": {
|
||||||
collector: collector,
|
collector: collector,
|
||||||
checker: stubUpgradeChecker{
|
checker: stubTerraformChecker{
|
||||||
err: assert.AnError,
|
err: assert.AnError,
|
||||||
},
|
},
|
||||||
csp: cloudprovider.GCP,
|
csp: cloudprovider.GCP,
|
||||||
@ -247,7 +247,7 @@ func TestUpgradeCheck(t *testing.T) {
|
|||||||
checkCmd := upgradeCheckCmd{
|
checkCmd := upgradeCheckCmd{
|
||||||
canUpgradeCheck: true,
|
canUpgradeCheck: true,
|
||||||
collect: &tc.collector,
|
collect: &tc.collector,
|
||||||
checker: tc.checker,
|
terraformChecker: tc.checker,
|
||||||
log: logger.NewTest(t),
|
log: logger.NewTest(t),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,31 +317,35 @@ func (s *stubVersionCollector) filterCompatibleCLIVersions(_ context.Context, _
|
|||||||
return s.newCompatibleCLIVersionsList, nil
|
return s.newCompatibleCLIVersionsList, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type stubUpgradeChecker struct {
|
type stubKubernetesChecker struct {
|
||||||
image string
|
image string
|
||||||
k8sVersion string
|
k8sVersion string
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s stubKubernetesChecker) CurrentImage(context.Context) (string, error) {
|
||||||
|
return s.image, s.err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s stubKubernetesChecker) CurrentKubernetesVersion(context.Context) (string, error) {
|
||||||
|
return s.k8sVersion, s.err
|
||||||
|
}
|
||||||
|
|
||||||
|
type stubTerraformChecker struct {
|
||||||
tfDiff bool
|
tfDiff bool
|
||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u stubUpgradeChecker) CurrentImage(context.Context) (string, error) {
|
func (s stubTerraformChecker) PlanTerraformMigrations(context.Context, upgrade.TerraformUpgradeOptions) (bool, error) {
|
||||||
return u.image, u.err
|
return s.tfDiff, s.err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u stubUpgradeChecker) CurrentKubernetesVersion(context.Context) (string, error) {
|
func (s stubTerraformChecker) CheckTerraformMigrations(_ string) error {
|
||||||
return u.k8sVersion, u.err
|
return s.err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u stubUpgradeChecker) PlanTerraformMigrations(context.Context, upgrade.TerraformUpgradeOptions) (bool, error) {
|
func (s stubTerraformChecker) CleanUpTerraformMigrations(_ string) error {
|
||||||
return u.tfDiff, u.err
|
return s.err
|
||||||
}
|
|
||||||
|
|
||||||
func (u stubUpgradeChecker) CheckTerraformMigrations(_ string) error {
|
|
||||||
return u.err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u stubUpgradeChecker) CleanUpTerraformMigrations(_ string) error {
|
|
||||||
return u.err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewCLIVersions(t *testing.T) {
|
func TestNewCLIVersions(t *testing.T) {
|
||||||
|
@ -11,25 +11,17 @@ go_library(
|
|||||||
importpath = "github.com/edgelesssys/constellation/v2/cli/internal/kubernetes",
|
importpath = "github.com/edgelesssys/constellation/v2/cli/internal/kubernetes",
|
||||||
visibility = ["//cli:__subpackages__"],
|
visibility = ["//cli:__subpackages__"],
|
||||||
deps = [
|
deps = [
|
||||||
"//cli/internal/clusterid",
|
|
||||||
"//cli/internal/helm",
|
|
||||||
"//cli/internal/terraform",
|
|
||||||
"//cli/internal/upgrade",
|
|
||||||
"//internal/api/versionsapi",
|
"//internal/api/versionsapi",
|
||||||
"//internal/attestation/variant",
|
"//internal/attestation/variant",
|
||||||
"//internal/cloud/cloudprovider",
|
"//internal/cloud/cloudprovider",
|
||||||
"//internal/compatibility",
|
"//internal/compatibility",
|
||||||
"//internal/config",
|
"//internal/config",
|
||||||
"//internal/constants",
|
"//internal/constants",
|
||||||
"//internal/file",
|
|
||||||
"//internal/imagefetcher",
|
"//internal/imagefetcher",
|
||||||
"//internal/kms/uri",
|
|
||||||
"//internal/kubernetes",
|
"//internal/kubernetes",
|
||||||
"//internal/kubernetes/kubectl",
|
|
||||||
"//internal/versions",
|
"//internal/versions",
|
||||||
"//internal/versions/components",
|
"//internal/versions/components",
|
||||||
"//operators/constellation-node-operator/api/v1alpha1",
|
"//operators/constellation-node-operator/api/v1alpha1",
|
||||||
"@com_github_google_uuid//:uuid",
|
|
||||||
"@io_k8s_api//core/v1:core",
|
"@io_k8s_api//core/v1:core",
|
||||||
"@io_k8s_apimachinery//pkg/api/errors",
|
"@io_k8s_apimachinery//pkg/api/errors",
|
||||||
"@io_k8s_apimachinery//pkg/apis/meta/v1:meta",
|
"@io_k8s_apimachinery//pkg/apis/meta/v1:meta",
|
||||||
|
@ -12,30 +12,20 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"path/filepath"
|
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/clusterid"
|
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/helm"
|
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/terraform"
|
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/upgrade"
|
|
||||||
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
|
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/compatibility"
|
"github.com/edgelesssys/constellation/v2/internal/compatibility"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/config"
|
"github.com/edgelesssys/constellation/v2/internal/config"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/constants"
|
"github.com/edgelesssys/constellation/v2/internal/constants"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/file"
|
|
||||||
"github.com/edgelesssys/constellation/v2/internal/imagefetcher"
|
"github.com/edgelesssys/constellation/v2/internal/imagefetcher"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/kms/uri"
|
|
||||||
internalk8s "github.com/edgelesssys/constellation/v2/internal/kubernetes"
|
internalk8s "github.com/edgelesssys/constellation/v2/internal/kubernetes"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/kubernetes/kubectl"
|
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versions"
|
"github.com/edgelesssys/constellation/v2/internal/versions"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versions/components"
|
"github.com/edgelesssys/constellation/v2/internal/versions/components"
|
||||||
updatev1alpha1 "github.com/edgelesssys/constellation/v2/operators/constellation-node-operator/v2/api/v1alpha1"
|
updatev1alpha1 "github.com/edgelesssys/constellation/v2/operators/constellation-node-operator/v2/api/v1alpha1"
|
||||||
"github.com/google/uuid"
|
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
k8serrors "k8s.io/apimachinery/pkg/api/errors"
|
k8serrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
@ -49,16 +39,6 @@ import (
|
|||||||
"sigs.k8s.io/yaml"
|
"sigs.k8s.io/yaml"
|
||||||
)
|
)
|
||||||
|
|
||||||
// UpgradeCmdKind is the kind of the upgrade command (check, apply).
|
|
||||||
type UpgradeCmdKind int
|
|
||||||
|
|
||||||
const (
|
|
||||||
// UpgradeCmdKindCheck corresponds to the upgrade check command.
|
|
||||||
UpgradeCmdKindCheck UpgradeCmdKind = iota
|
|
||||||
// UpgradeCmdKindApply corresponds to the upgrade apply command.
|
|
||||||
UpgradeCmdKindApply
|
|
||||||
)
|
|
||||||
|
|
||||||
// ErrInProgress signals that an upgrade is in progress inside the cluster.
|
// ErrInProgress signals that an upgrade is in progress inside the cluster.
|
||||||
var ErrInProgress = errors.New("upgrade in progress")
|
var ErrInProgress = errors.New("upgrade in progress")
|
||||||
|
|
||||||
@ -91,69 +71,36 @@ func (e *applyError) Error() string {
|
|||||||
type Upgrader struct {
|
type Upgrader struct {
|
||||||
stableInterface StableInterface
|
stableInterface StableInterface
|
||||||
dynamicInterface DynamicInterface
|
dynamicInterface DynamicInterface
|
||||||
helmClient helmInterface
|
|
||||||
imageFetcher imageFetcher
|
imageFetcher imageFetcher
|
||||||
outWriter io.Writer
|
outWriter io.Writer
|
||||||
tfUpgrader *upgrade.TerraformUpgrader
|
|
||||||
log debugLog
|
log debugLog
|
||||||
upgradeID string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewUpgrader returns a new Upgrader.
|
// NewUpgrader returns a new Upgrader.
|
||||||
func NewUpgrader(
|
func NewUpgrader(outWriter io.Writer, kubeConfigPath string, log debugLog) (*Upgrader, error) {
|
||||||
ctx context.Context, outWriter io.Writer, upgradeWorkspace, kubeConfigPath string,
|
|
||||||
fileHandler file.Handler, log debugLog, upgradeCmdKind UpgradeCmdKind,
|
|
||||||
) (*Upgrader, error) {
|
|
||||||
upgradeID := "upgrade-" + time.Now().Format("20060102150405") + "-" + strings.Split(uuid.New().String(), "-")[0]
|
|
||||||
if upgradeCmdKind == UpgradeCmdKindCheck {
|
|
||||||
// When performing an upgrade check, the upgrade directory will only be used temporarily to store the
|
|
||||||
// Terraform state. The directory is deleted after the check is finished.
|
|
||||||
// Therefore, add a tmp-suffix to the upgrade ID to indicate that the directory will be cleared after the check.
|
|
||||||
upgradeID += "-tmp"
|
|
||||||
}
|
|
||||||
|
|
||||||
u := &Upgrader{
|
|
||||||
imageFetcher: imagefetcher.New(),
|
|
||||||
outWriter: outWriter,
|
|
||||||
log: log,
|
|
||||||
upgradeID: upgradeID,
|
|
||||||
}
|
|
||||||
|
|
||||||
kubeClient, err := newClient(kubeConfigPath)
|
kubeClient, err := newClient(kubeConfigPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
u.stableInterface = &stableClient{client: kubeClient}
|
|
||||||
|
|
||||||
// use unstructured client to avoid importing the operator packages
|
// use unstructured client to avoid importing the operator packages
|
||||||
kubeConfig, err := clientcmd.BuildConfigFromFlags("", kubeConfigPath)
|
kubeConfig, err := clientcmd.BuildConfigFromFlags("", kubeConfigPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("building kubernetes config: %w", err)
|
return nil, fmt.Errorf("building kubernetes config: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
unstructuredClient, err := dynamic.NewForConfig(kubeConfig)
|
unstructuredClient, err := dynamic.NewForConfig(kubeConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("setting up custom resource client: %w", err)
|
return nil, fmt.Errorf("setting up custom resource client: %w", err)
|
||||||
}
|
}
|
||||||
u.dynamicInterface = &NodeVersionClient{client: unstructuredClient}
|
|
||||||
|
|
||||||
helmClient, err := helm.NewUpgradeClient(kubectl.New(), upgradeWorkspace, kubeConfigPath, constants.HelmNamespace, log)
|
return &Upgrader{
|
||||||
if err != nil {
|
imageFetcher: imagefetcher.New(),
|
||||||
return nil, fmt.Errorf("setting up helm client: %w", err)
|
outWriter: outWriter,
|
||||||
}
|
log: log,
|
||||||
u.helmClient = helmClient
|
stableInterface: &stableClient{client: kubeClient},
|
||||||
|
dynamicInterface: &NodeVersionClient{client: unstructuredClient},
|
||||||
tfClient, err := terraform.New(ctx, filepath.Join(upgradeWorkspace, upgradeID, constants.TerraformUpgradeWorkingDir))
|
}, nil
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("setting up terraform client: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
tfUpgrader, err := upgrade.NewTerraformUpgrader(tfClient, outWriter, fileHandler)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("setting up terraform upgrader: %w", err)
|
|
||||||
}
|
|
||||||
u.tfUpgrader = tfUpgrader
|
|
||||||
|
|
||||||
return u, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMeasurementSalt returns the measurementSalt from the join-config.
|
// GetMeasurementSalt returns the measurementSalt from the join-config.
|
||||||
@ -169,47 +116,6 @@ func (u *Upgrader) GetMeasurementSalt(ctx context.Context) ([]byte, error) {
|
|||||||
return salt, nil
|
return salt, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUpgradeID returns the upgrade ID.
|
|
||||||
func (u *Upgrader) GetUpgradeID() string {
|
|
||||||
return u.upgradeID
|
|
||||||
}
|
|
||||||
|
|
||||||
// CheckTerraformMigrations checks whether Terraform migrations are possible in the current workspace.
|
|
||||||
// If the files that will be written during the upgrade already exist, it returns an error.
|
|
||||||
func (u *Upgrader) CheckTerraformMigrations(upgradeWorkspace string) error {
|
|
||||||
return u.tfUpgrader.CheckTerraformMigrations(upgradeWorkspace, u.upgradeID, constants.TerraformUpgradeBackupDir)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CleanUpTerraformMigrations cleans up the Terraform migration workspace, for example when an upgrade is
|
|
||||||
// aborted by the user.
|
|
||||||
func (u *Upgrader) CleanUpTerraformMigrations(upgradeWorkspace string) error {
|
|
||||||
return u.tfUpgrader.CleanUpTerraformMigrations(upgradeWorkspace, u.upgradeID)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PlanTerraformMigrations prepares the upgrade workspace and plans the Terraform migrations for the Constellation upgrade.
|
|
||||||
// If a diff exists, it's being written to the upgrader's output writer. It also returns
|
|
||||||
// a bool indicating whether a diff exists.
|
|
||||||
func (u *Upgrader) PlanTerraformMigrations(ctx context.Context, opts upgrade.TerraformUpgradeOptions) (bool, error) {
|
|
||||||
return u.tfUpgrader.PlanTerraformMigrations(ctx, opts, u.upgradeID)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ApplyTerraformMigrations applies the migrations planned by PlanTerraformMigrations.
|
|
||||||
// If PlanTerraformMigrations has not been executed before, it will return an error.
|
|
||||||
// In case of a successful upgrade, the output will be written to the specified file and the old Terraform directory is replaced
|
|
||||||
// By the new one.
|
|
||||||
func (u *Upgrader) ApplyTerraformMigrations(ctx context.Context, opts upgrade.TerraformUpgradeOptions) (terraform.ApplyOutput, error) {
|
|
||||||
return u.tfUpgrader.ApplyTerraformMigrations(ctx, opts, u.upgradeID)
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpgradeHelmServices upgrade helm services.
|
|
||||||
func (u *Upgrader) UpgradeHelmServices(ctx context.Context, config *config.Config, idFile clusterid.File, timeout time.Duration,
|
|
||||||
allowDestructive bool, force bool, conformance bool, helmWaitMode helm.WaitMode, masterSecret uri.MasterSecret, serviceAccURI string,
|
|
||||||
validK8sVersion versions.ValidK8sVersion, output terraform.ApplyOutput,
|
|
||||||
) error {
|
|
||||||
return u.helmClient.Upgrade(ctx, config, idFile, timeout, allowDestructive, force, u.upgradeID, conformance,
|
|
||||||
helmWaitMode, masterSecret, serviceAccURI, validK8sVersion, output)
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpgradeNodeVersion upgrades the cluster's NodeVersion object and in turn triggers image & k8s version upgrades.
|
// UpgradeNodeVersion upgrades the cluster's NodeVersion object and in turn triggers image & k8s version upgrades.
|
||||||
// The versions set in the config are validated against the versions running in the cluster.
|
// The versions set in the config are validated against the versions running in the cluster.
|
||||||
func (u *Upgrader) UpgradeNodeVersion(ctx context.Context, conf *config.Config, force bool) error {
|
func (u *Upgrader) UpgradeNodeVersion(ctx context.Context, conf *config.Config, force bool) error {
|
||||||
@ -569,10 +475,6 @@ func upgradeInProgress(nodeVersion updatev1alpha1.NodeVersion) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
type helmInterface interface {
|
|
||||||
Upgrade(ctx context.Context, config *config.Config, idFile clusterid.File, timeout time.Duration, allowDestructive, force bool, upgradeID string, conformance bool, helmWaitMode helm.WaitMode, masterSecret uri.MasterSecret, serviceAccURI string, validK8sVersion versions.ValidK8sVersion, output terraform.ApplyOutput) error
|
|
||||||
}
|
|
||||||
|
|
||||||
type debugLog interface {
|
type debugLog interface {
|
||||||
Debugf(format string, args ...any)
|
Debugf(format string, args ...any)
|
||||||
Sync()
|
Sync()
|
||||||
|
@ -21,24 +21,6 @@ import (
|
|||||||
"github.com/edgelesssys/constellation/v2/internal/file"
|
"github.com/edgelesssys/constellation/v2/internal/file"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewTerraformUpgrader returns a new TerraformUpgrader.
|
|
||||||
func NewTerraformUpgrader(tfClient tfResourceClient, outWriter io.Writer, fileHandler file.Handler) (*TerraformUpgrader, error) {
|
|
||||||
return &TerraformUpgrader{
|
|
||||||
tf: tfClient,
|
|
||||||
policyPatcher: cloudcmd.NewAzurePolicyPatcher(),
|
|
||||||
outWriter: outWriter,
|
|
||||||
fileHandler: fileHandler,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// TerraformUpgrader is responsible for performing Terraform migrations on cluster upgrades.
|
|
||||||
type TerraformUpgrader struct {
|
|
||||||
tf tfResourceClient
|
|
||||||
policyPatcher policyPatcher
|
|
||||||
outWriter io.Writer
|
|
||||||
fileHandler file.Handler
|
|
||||||
}
|
|
||||||
|
|
||||||
// TerraformUpgradeOptions are the options used for the Terraform upgrade.
|
// TerraformUpgradeOptions are the options used for the Terraform upgrade.
|
||||||
type TerraformUpgradeOptions struct {
|
type TerraformUpgradeOptions struct {
|
||||||
// LogLevel is the log level used for Terraform.
|
// LogLevel is the log level used for Terraform.
|
||||||
@ -51,55 +33,43 @@ type TerraformUpgradeOptions struct {
|
|||||||
UpgradeWorkspace string
|
UpgradeWorkspace string
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckTerraformMigrations checks whether Terraform migrations are possible in the current workspace.
|
// TerraformUpgrader is responsible for performing Terraform migrations on cluster upgrades.
|
||||||
func checkTerraformMigrations(file file.Handler, upgradeWorkspace, upgradeID, upgradeSubDir string) error {
|
type TerraformUpgrader struct {
|
||||||
var existingFiles []string
|
tf tfResourceClient
|
||||||
filesToCheck := []string{
|
policyPatcher policyPatcher
|
||||||
filepath.Join(upgradeWorkspace, upgradeID, upgradeSubDir),
|
outWriter io.Writer
|
||||||
|
fileHandler file.Handler
|
||||||
|
upgradeID string
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, f := range filesToCheck {
|
// NewTerraformUpgrader returns a new TerraformUpgrader.
|
||||||
if err := checkFileExists(file, &existingFiles, f); err != nil {
|
func NewTerraformUpgrader(tfClient tfResourceClient, outWriter io.Writer, fileHandler file.Handler, upgradeID string,
|
||||||
return fmt.Errorf("checking terraform migrations: %w", err)
|
) *TerraformUpgrader {
|
||||||
|
return &TerraformUpgrader{
|
||||||
|
tf: tfClient,
|
||||||
|
policyPatcher: cloudcmd.NewAzurePolicyPatcher(),
|
||||||
|
outWriter: outWriter,
|
||||||
|
fileHandler: fileHandler,
|
||||||
|
upgradeID: upgradeID,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(existingFiles) > 0 {
|
|
||||||
return fmt.Errorf("file(s) %s already exist", strings.Join(existingFiles, ", "))
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CheckTerraformMigrations checks whether Terraform migrations are possible in the current workspace.
|
// CheckTerraformMigrations checks whether Terraform migrations are possible in the current workspace.
|
||||||
// If the files that will be written during the upgrade already exist, it returns an error.
|
// If the files that will be written during the upgrade already exist, it returns an error.
|
||||||
func (u *TerraformUpgrader) CheckTerraformMigrations(upgradeWorkspace, upgradeID, upgradeSubDir string) error {
|
func (u *TerraformUpgrader) CheckTerraformMigrations(upgradeWorkspace string) error {
|
||||||
return checkTerraformMigrations(u.fileHandler, upgradeWorkspace, upgradeID, upgradeSubDir)
|
return checkTerraformMigrations(u.fileHandler, upgradeWorkspace, u.upgradeID, constants.TerraformUpgradeBackupDir)
|
||||||
}
|
|
||||||
|
|
||||||
// checkFileExists checks whether a file exists and adds it to the existingFiles slice if it does.
|
|
||||||
func checkFileExists(fileHandler file.Handler, existingFiles *[]string, filename string) error {
|
|
||||||
_, err := fileHandler.Stat(filename)
|
|
||||||
if err != nil {
|
|
||||||
if !os.IsNotExist(err) {
|
|
||||||
return fmt.Errorf("checking %s: %w", filename, err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
*existingFiles = append(*existingFiles, filename)
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// PlanTerraformMigrations prepares the upgrade workspace and plans the Terraform migrations for the Constellation upgrade.
|
// PlanTerraformMigrations prepares the upgrade workspace and plans the Terraform migrations for the Constellation upgrade.
|
||||||
// If a diff exists, it's being written to the upgrader's output writer. It also returns
|
// If a diff exists, it's being written to the upgrader's output writer. It also returns
|
||||||
// a bool indicating whether a diff exists.
|
// a bool indicating whether a diff exists.
|
||||||
func (u *TerraformUpgrader) PlanTerraformMigrations(ctx context.Context, opts TerraformUpgradeOptions, upgradeID string) (bool, error) {
|
func (u *TerraformUpgrader) PlanTerraformMigrations(ctx context.Context, opts TerraformUpgradeOptions) (bool, error) {
|
||||||
// Prepare the new Terraform workspace and backup the old one
|
// Prepare the new Terraform workspace and backup the old one
|
||||||
err := u.tf.PrepareUpgradeWorkspace(
|
err := u.tf.PrepareUpgradeWorkspace(
|
||||||
filepath.Join("terraform", strings.ToLower(opts.CSP.String())),
|
filepath.Join("terraform", strings.ToLower(opts.CSP.String())),
|
||||||
opts.TFWorkspace,
|
opts.TFWorkspace,
|
||||||
filepath.Join(opts.UpgradeWorkspace, upgradeID, constants.TerraformUpgradeWorkingDir),
|
filepath.Join(opts.UpgradeWorkspace, u.upgradeID, constants.TerraformUpgradeWorkingDir),
|
||||||
filepath.Join(opts.UpgradeWorkspace, upgradeID, constants.TerraformUpgradeBackupDir),
|
filepath.Join(opts.UpgradeWorkspace, u.upgradeID, constants.TerraformUpgradeBackupDir),
|
||||||
opts.Vars,
|
opts.Vars,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -122,24 +92,15 @@ func (u *TerraformUpgrader) PlanTerraformMigrations(ctx context.Context, opts Te
|
|||||||
|
|
||||||
// CleanUpTerraformMigrations cleans up the Terraform migration workspace, for example when an upgrade is
|
// CleanUpTerraformMigrations cleans up the Terraform migration workspace, for example when an upgrade is
|
||||||
// aborted by the user.
|
// aborted by the user.
|
||||||
func (u *TerraformUpgrader) CleanUpTerraformMigrations(upgradeWorkspace, upgradeID string) error {
|
func (u *TerraformUpgrader) CleanUpTerraformMigrations(upgradeWorkspace string) error {
|
||||||
return CleanUpTerraformMigrations(upgradeWorkspace, upgradeID, u.fileHandler)
|
return CleanUpTerraformMigrations(upgradeWorkspace, u.upgradeID, u.fileHandler)
|
||||||
}
|
|
||||||
|
|
||||||
// CleanUpTerraformMigrations cleans up the Terraform upgrade directory.
|
|
||||||
func CleanUpTerraformMigrations(upgradeWorkspace, upgradeID string, fileHandler file.Handler) error {
|
|
||||||
upgradeDir := filepath.Join(upgradeWorkspace, upgradeID)
|
|
||||||
if err := fileHandler.RemoveAll(upgradeDir); err != nil {
|
|
||||||
return fmt.Errorf("cleaning up file %s: %w", upgradeDir, err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ApplyTerraformMigrations applies the migrations planned by PlanTerraformMigrations.
|
// ApplyTerraformMigrations applies the migrations planned by PlanTerraformMigrations.
|
||||||
// If PlanTerraformMigrations has not been executed before, it will return an error.
|
// If PlanTerraformMigrations has not been executed before, it will return an error.
|
||||||
// In case of a successful upgrade, the output will be written to the specified file and the old Terraform directory is replaced
|
// In case of a successful upgrade, the output will be written to the specified file and the old Terraform directory is replaced
|
||||||
// By the new one.
|
// By the new one.
|
||||||
func (u *TerraformUpgrader) ApplyTerraformMigrations(ctx context.Context, opts TerraformUpgradeOptions, upgradeID string) (terraform.ApplyOutput, error) {
|
func (u *TerraformUpgrader) ApplyTerraformMigrations(ctx context.Context, opts TerraformUpgradeOptions) (terraform.ApplyOutput, error) {
|
||||||
tfOutput, err := u.tf.CreateCluster(ctx, opts.CSP, opts.LogLevel)
|
tfOutput, err := u.tf.CreateCluster(ctx, opts.CSP, opts.LogLevel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return tfOutput, fmt.Errorf("terraform apply: %w", err)
|
return tfOutput, fmt.Errorf("terraform apply: %w", err)
|
||||||
@ -154,17 +115,64 @@ func (u *TerraformUpgrader) ApplyTerraformMigrations(ctx context.Context, opts T
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := u.fileHandler.CopyDir(
|
if err := u.fileHandler.CopyDir(
|
||||||
filepath.Join(opts.UpgradeWorkspace, upgradeID, constants.TerraformUpgradeWorkingDir),
|
filepath.Join(opts.UpgradeWorkspace, u.upgradeID, constants.TerraformUpgradeWorkingDir),
|
||||||
opts.TFWorkspace,
|
opts.TFWorkspace,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return tfOutput, fmt.Errorf("replacing old terraform directory with new one: %w", err)
|
return tfOutput, fmt.Errorf("replacing old terraform directory with new one: %w", err)
|
||||||
}
|
}
|
||||||
if err := u.fileHandler.RemoveAll(filepath.Join(opts.UpgradeWorkspace, upgradeID, constants.TerraformUpgradeWorkingDir)); err != nil {
|
if err := u.fileHandler.RemoveAll(filepath.Join(opts.UpgradeWorkspace, u.upgradeID, constants.TerraformUpgradeWorkingDir)); err != nil {
|
||||||
return tfOutput, fmt.Errorf("removing terraform upgrade directory: %w", err)
|
return tfOutput, fmt.Errorf("removing terraform upgrade directory: %w", err)
|
||||||
}
|
}
|
||||||
return tfOutput, nil
|
return tfOutput, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpgradeID returns the ID of the upgrade.
|
||||||
|
func (u *TerraformUpgrader) UpgradeID() string {
|
||||||
|
return u.upgradeID
|
||||||
|
}
|
||||||
|
|
||||||
|
// CleanUpTerraformMigrations cleans up the Terraform upgrade directory.
|
||||||
|
func CleanUpTerraformMigrations(upgradeWorkspace, upgradeID string, fileHandler file.Handler) error {
|
||||||
|
upgradeDir := filepath.Join(upgradeWorkspace, upgradeID)
|
||||||
|
if err := fileHandler.RemoveAll(upgradeDir); err != nil {
|
||||||
|
return fmt.Errorf("cleaning up file %s: %w", upgradeDir, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckTerraformMigrations checks whether Terraform migrations are possible in the current workspace.
|
||||||
|
func checkTerraformMigrations(file file.Handler, upgradeWorkspace, upgradeID, upgradeSubDir string) error {
|
||||||
|
var existingFiles []string
|
||||||
|
filesToCheck := []string{
|
||||||
|
filepath.Join(upgradeWorkspace, upgradeID, upgradeSubDir),
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, f := range filesToCheck {
|
||||||
|
if err := checkFileExists(file, &existingFiles, f); err != nil {
|
||||||
|
return fmt.Errorf("checking terraform migrations: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(existingFiles) > 0 {
|
||||||
|
return fmt.Errorf("file(s) %s already exist", strings.Join(existingFiles, ", "))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// checkFileExists checks whether a file exists and adds it to the existingFiles slice if it does.
|
||||||
|
func checkFileExists(fileHandler file.Handler, existingFiles *[]string, filename string) error {
|
||||||
|
_, err := fileHandler.Stat(filename)
|
||||||
|
if err != nil {
|
||||||
|
if !os.IsNotExist(err) {
|
||||||
|
return fmt.Errorf("checking %s: %w", filename, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
*existingFiles = append(*existingFiles, filename)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type tfClientCommon interface {
|
type tfClientCommon interface {
|
||||||
ShowPlan(ctx context.Context, logLevel terraform.LogLevel, output io.Writer) error
|
ShowPlan(ctx context.Context, logLevel terraform.LogLevel, output io.Writer) error
|
||||||
Plan(ctx context.Context, logLevel terraform.LogLevel) (bool, error)
|
Plan(ctx context.Context, logLevel terraform.LogLevel) (bool, error)
|
||||||
|
@ -23,13 +23,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestCheckTerraformMigrations(t *testing.T) {
|
func TestCheckTerraformMigrations(t *testing.T) {
|
||||||
upgrader := func(fileHandler file.Handler) *TerraformUpgrader {
|
|
||||||
u, err := NewTerraformUpgrader(&stubTerraformClient{}, bytes.NewBuffer(nil), fileHandler)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
return u
|
|
||||||
}
|
|
||||||
|
|
||||||
workspace := func(existingFiles []string) file.Handler {
|
workspace := func(existingFiles []string) file.Handler {
|
||||||
fs := afero.NewMemMapFs()
|
fs := afero.NewMemMapFs()
|
||||||
for _, f := range existingFiles {
|
for _, f := range existingFiles {
|
||||||
@ -57,8 +50,9 @@ func TestCheckTerraformMigrations(t *testing.T) {
|
|||||||
|
|
||||||
for name, tc := range testCases {
|
for name, tc := range testCases {
|
||||||
t.Run(name, func(t *testing.T) {
|
t.Run(name, func(t *testing.T) {
|
||||||
u := upgrader(tc.workspace)
|
u := NewTerraformUpgrader(&stubTerraformClient{}, bytes.NewBuffer(nil), tc.workspace, tc.upgradeID)
|
||||||
err := u.CheckTerraformMigrations(constants.UpgradeDir, tc.upgradeID, constants.TerraformUpgradeBackupDir)
|
|
||||||
|
err := u.CheckTerraformMigrations(constants.UpgradeDir)
|
||||||
if tc.wantErr {
|
if tc.wantErr {
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
return
|
return
|
||||||
@ -70,12 +64,6 @@ func TestCheckTerraformMigrations(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPlanTerraformMigrations(t *testing.T) {
|
func TestPlanTerraformMigrations(t *testing.T) {
|
||||||
upgrader := func(tf tfResourceClient, fileHandler file.Handler) *TerraformUpgrader {
|
|
||||||
u, err := NewTerraformUpgrader(tf, bytes.NewBuffer(nil), fileHandler)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
return u
|
|
||||||
}
|
|
||||||
workspace := func(existingFiles []string) file.Handler {
|
workspace := func(existingFiles []string) file.Handler {
|
||||||
fs := afero.NewMemMapFs()
|
fs := afero.NewMemMapFs()
|
||||||
for _, f := range existingFiles {
|
for _, f := range existingFiles {
|
||||||
@ -142,7 +130,7 @@ func TestPlanTerraformMigrations(t *testing.T) {
|
|||||||
t.Run(name, func(t *testing.T) {
|
t.Run(name, func(t *testing.T) {
|
||||||
require := require.New(t)
|
require := require.New(t)
|
||||||
|
|
||||||
u := upgrader(tc.tf, tc.workspace)
|
u := NewTerraformUpgrader(tc.tf, bytes.NewBuffer(nil), tc.workspace, tc.upgradeID)
|
||||||
|
|
||||||
opts := TerraformUpgradeOptions{
|
opts := TerraformUpgradeOptions{
|
||||||
LogLevel: terraform.LogLevelDebug,
|
LogLevel: terraform.LogLevelDebug,
|
||||||
@ -150,7 +138,7 @@ func TestPlanTerraformMigrations(t *testing.T) {
|
|||||||
Vars: &terraform.QEMUVariables{},
|
Vars: &terraform.QEMUVariables{},
|
||||||
}
|
}
|
||||||
|
|
||||||
diff, err := u.PlanTerraformMigrations(context.Background(), opts, tc.upgradeID)
|
diff, err := u.PlanTerraformMigrations(context.Background(), opts)
|
||||||
if tc.wantErr {
|
if tc.wantErr {
|
||||||
require.Error(err)
|
require.Error(err)
|
||||||
} else {
|
} else {
|
||||||
@ -162,13 +150,6 @@ func TestPlanTerraformMigrations(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestApplyTerraformMigrations(t *testing.T) {
|
func TestApplyTerraformMigrations(t *testing.T) {
|
||||||
upgrader := func(tf tfResourceClient, fileHandler file.Handler) *TerraformUpgrader {
|
|
||||||
u, err := NewTerraformUpgrader(tf, bytes.NewBuffer(nil), fileHandler)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
return u
|
|
||||||
}
|
|
||||||
|
|
||||||
fileHandler := func(upgradeID string, existingFiles ...string) file.Handler {
|
fileHandler := func(upgradeID string, existingFiles ...string) file.Handler {
|
||||||
fh := file.NewHandler(afero.NewMemMapFs())
|
fh := file.NewHandler(afero.NewMemMapFs())
|
||||||
|
|
||||||
@ -211,7 +192,7 @@ func TestApplyTerraformMigrations(t *testing.T) {
|
|||||||
t.Run(name, func(t *testing.T) {
|
t.Run(name, func(t *testing.T) {
|
||||||
require := require.New(t)
|
require := require.New(t)
|
||||||
|
|
||||||
u := upgrader(tc.tf, tc.fs)
|
u := NewTerraformUpgrader(tc.tf, bytes.NewBuffer(nil), tc.fs, tc.upgradeID)
|
||||||
|
|
||||||
opts := TerraformUpgradeOptions{
|
opts := TerraformUpgradeOptions{
|
||||||
LogLevel: terraform.LogLevelDebug,
|
LogLevel: terraform.LogLevelDebug,
|
||||||
@ -221,7 +202,7 @@ func TestApplyTerraformMigrations(t *testing.T) {
|
|||||||
UpgradeWorkspace: constants.UpgradeDir,
|
UpgradeWorkspace: constants.UpgradeDir,
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := u.ApplyTerraformMigrations(context.Background(), opts, tc.upgradeID)
|
_, err := u.ApplyTerraformMigrations(context.Background(), opts)
|
||||||
if tc.wantErr {
|
if tc.wantErr {
|
||||||
require.Error(err)
|
require.Error(err)
|
||||||
} else {
|
} else {
|
||||||
@ -232,13 +213,6 @@ func TestApplyTerraformMigrations(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestCleanUpTerraformMigrations(t *testing.T) {
|
func TestCleanUpTerraformMigrations(t *testing.T) {
|
||||||
upgrader := func(fileHandler file.Handler) *TerraformUpgrader {
|
|
||||||
u, err := NewTerraformUpgrader(&stubTerraformClient{}, bytes.NewBuffer(nil), fileHandler)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
return u
|
|
||||||
}
|
|
||||||
|
|
||||||
workspace := func(existingFiles []string) file.Handler {
|
workspace := func(existingFiles []string) file.Handler {
|
||||||
fs := afero.NewMemMapFs()
|
fs := afero.NewMemMapFs()
|
||||||
for _, f := range existingFiles {
|
for _, f := range existingFiles {
|
||||||
@ -299,9 +273,9 @@ func TestCleanUpTerraformMigrations(t *testing.T) {
|
|||||||
require := require.New(t)
|
require := require.New(t)
|
||||||
|
|
||||||
workspace := workspace(tc.workspaceFiles)
|
workspace := workspace(tc.workspaceFiles)
|
||||||
u := upgrader(workspace)
|
u := NewTerraformUpgrader(&stubTerraformClient{}, bytes.NewBuffer(nil), workspace, tc.upgradeID)
|
||||||
|
|
||||||
err := u.CleanUpTerraformMigrations(constants.UpgradeDir, tc.upgradeID)
|
err := u.CleanUpTerraformMigrations(constants.UpgradeDir)
|
||||||
if tc.wantErr {
|
if tc.wantErr {
|
||||||
require.Error(err)
|
require.Error(err)
|
||||||
return
|
return
|
||||||
|
Loading…
Reference in New Issue
Block a user