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 (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/edgelesssys/constellation/v2/cli/internal/terraform"
|
||||
"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/constants"
|
||||
"github.com/edgelesssys/constellation/v2/internal/file"
|
||||
"github.com/google/uuid"
|
||||
"github.com/spf13/afero"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
@ -70,7 +67,8 @@ func runIAMUpgradeApply(cmd *cobra.Command, _ []string) error {
|
||||
if err != nil {
|
||||
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)
|
||||
if err != nil {
|
||||
return fmt.Errorf("setting up IAM migration command: %w", err)
|
||||
@ -86,10 +84,10 @@ func runIAMUpgradeApply(cmd *cobra.Command, _ []string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = migrator.applyMigration(cmd, constants.UpgradeDir, file.NewHandler(afero.NewOsFs()), iamMigrateCmd, yes)
|
||||
if err != nil {
|
||||
if err := migrator.applyMigration(cmd, constants.UpgradeDir, file.NewHandler(afero.NewOsFs()), iamMigrateCmd, yes); err != nil {
|
||||
return fmt.Errorf("applying IAM migration: %w", err)
|
||||
}
|
||||
|
||||
cmd.Println("IAM profile successfully applied.")
|
||||
return nil
|
||||
}
|
||||
|
@ -7,6 +7,10 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@ -23,3 +27,31 @@ func NewUpgradeCmd() *cobra.Command {
|
||||
cmd.AddCommand(newUpgradeApplyCmd())
|
||||
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/file"
|
||||
"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/rogpeppe/go-internal/diff"
|
||||
"github.com/spf13/afero"
|
||||
@ -64,33 +65,54 @@ func runUpgradeApply(cmd *cobra.Command, _ []string) error {
|
||||
return fmt.Errorf("creating logger: %w", err)
|
||||
}
|
||||
defer log.Sync()
|
||||
fileHandler := file.NewHandler(afero.NewOsFs())
|
||||
|
||||
upgrader, err := kubernetes.NewUpgrader(
|
||||
cmd.Context(), cmd.OutOrStdout(),
|
||||
constants.UpgradeDir, constants.AdminConfFilename,
|
||||
fileHandler, log, kubernetes.UpgradeCmdKindApply,
|
||||
)
|
||||
fileHandler := file.NewHandler(afero.NewOsFs())
|
||||
upgradeID := generateUpgradeID(upgradeCmdKindApply)
|
||||
|
||||
kubeUpgrader, err := kubernetes.NewUpgrader(cmd.OutOrStdout(), constants.AdminConfFilename, log)
|
||||
if err != nil {
|
||||
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()
|
||||
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 {
|
||||
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)
|
||||
}
|
||||
|
||||
type upgradeApplyCmd struct {
|
||||
upgrader cloudUpgrader
|
||||
configFetcher attestationconfigapi.Fetcher
|
||||
clusterShower clusterShower
|
||||
fileHandler file.Handler
|
||||
log debugLog
|
||||
helmUpgrader helmUpgrader
|
||||
kubeUpgrader kubernetesUpgrader
|
||||
terraformUpgrader terraformUpgrader
|
||||
configFetcher attestationconfigapi.Fetcher
|
||||
clusterShower clusterShower
|
||||
fileHandler file.Handler
|
||||
log debugLog
|
||||
}
|
||||
|
||||
func (u *upgradeApplyCmd) upgradeApply(cmd *cobra.Command) error {
|
||||
@ -131,7 +153,7 @@ func (u *upgradeApplyCmd) upgradeApply(cmd *cobra.Command) error {
|
||||
}
|
||||
if idFile.MeasurementSalt == nil {
|
||||
// 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 {
|
||||
return fmt.Errorf("getting join-config: %w", err)
|
||||
}
|
||||
@ -161,7 +183,7 @@ func (u *upgradeApplyCmd) upgradeApply(cmd *cobra.Command) error {
|
||||
// - fallback endpoint
|
||||
// - custom (user-provided) endpoint
|
||||
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)
|
||||
}
|
||||
|
||||
@ -177,7 +199,7 @@ func (u *upgradeApplyCmd) upgradeApply(cmd *cobra.Command) error {
|
||||
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 {
|
||||
case errors.Is(err, kubernetes.ErrInProgress):
|
||||
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) {
|
||||
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)
|
||||
}
|
||||
|
||||
@ -242,7 +264,7 @@ func (u *upgradeApplyCmd) migrateTerraform(
|
||||
// u.upgrader.AddManualStateMigration(migration)
|
||||
// }
|
||||
|
||||
hasDiff, err := u.upgrader.PlanTerraformMigrations(cmd.Context(), opts)
|
||||
hasDiff, err := u.terraformUpgrader.PlanTerraformMigrations(cmd.Context(), opts)
|
||||
if err != nil {
|
||||
return res, fmt.Errorf("planning terraform migrations: %w", err)
|
||||
}
|
||||
@ -257,14 +279,14 @@ func (u *upgradeApplyCmd) migrateTerraform(
|
||||
}
|
||||
if !ok {
|
||||
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("aborted by user")
|
||||
}
|
||||
}
|
||||
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 {
|
||||
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"+
|
||||
"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 {
|
||||
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.
|
||||
// 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 {
|
||||
clusterAttestationConfig, err := u.upgrader.GetClusterAttestationConfig(cmd.Context(), newConfig.GetVariant())
|
||||
clusterAttestationConfig, err := u.kubeUpgrader.GetClusterAttestationConfig(cmd.Context(), newConfig.GetVariant())
|
||||
if err != nil {
|
||||
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.
|
||||
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)
|
||||
}
|
||||
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 nil
|
||||
@ -375,7 +399,11 @@ func (u *upgradeApplyCmd) handleServiceUpgrade(cmd *cobra.Command, conf *config.
|
||||
if err != nil {
|
||||
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 !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.")
|
||||
@ -388,7 +416,11 @@ func (u *upgradeApplyCmd) handleServiceUpgrade(cmd *cobra.Command, conf *config.
|
||||
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
|
||||
@ -470,17 +502,27 @@ type upgradeApplyFlags struct {
|
||||
helmWaitMode helm.WaitMode
|
||||
}
|
||||
|
||||
type cloudUpgrader interface {
|
||||
type kubernetesUpgrader interface {
|
||||
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
|
||||
GetClusterAttestationConfig(ctx context.Context, variant variant.Variant) (config.AttestationCfg, error)
|
||||
UpdateAttestationConfig(ctx context.Context, newAttestConfig config.AttestationCfg) 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)
|
||||
ApplyTerraformMigrations(ctx context.Context, opts upgrade.TerraformUpgradeOptions) (terraform.ApplyOutput, error)
|
||||
CheckTerraformMigrations(upgradeWorkspace string) error
|
||||
CleanUpTerraformMigrations(upgradeWorkspace string) error
|
||||
GetUpgradeID() string
|
||||
BackupConfigMap(ctx context.Context, name string) error
|
||||
UpgradeID() string
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ package cmd
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@ -32,87 +31,106 @@ import (
|
||||
)
|
||||
|
||||
func TestUpgradeApply(t *testing.T) {
|
||||
someErr := errors.New("some error")
|
||||
testCases := map[string]struct {
|
||||
upgrader *stubUpgrader
|
||||
helmUpgrader *stubHelmUpgrader
|
||||
kubeUpgrader *stubKubernetesUpgrader
|
||||
terraformUpgrader *stubTerraformUpgrader
|
||||
wantErr bool
|
||||
yesFlag bool
|
||||
dontWantJoinConfigBackup bool
|
||||
stdin string
|
||||
}{
|
||||
"success": {
|
||||
upgrader: &stubUpgrader{currentConfig: config.DefaultForAzureSEVSNP()},
|
||||
yesFlag: true,
|
||||
kubeUpgrader: &stubKubernetesUpgrader{currentConfig: config.DefaultForAzureSEVSNP()},
|
||||
helmUpgrader: &stubHelmUpgrader{},
|
||||
terraformUpgrader: &stubTerraformUpgrader{},
|
||||
yesFlag: true,
|
||||
},
|
||||
"nodeVersion some error": {
|
||||
upgrader: &stubUpgrader{
|
||||
kubeUpgrader: &stubKubernetesUpgrader{
|
||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
||||
nodeVersionErr: someErr,
|
||||
nodeVersionErr: assert.AnError,
|
||||
},
|
||||
wantErr: true,
|
||||
yesFlag: true,
|
||||
helmUpgrader: &stubHelmUpgrader{},
|
||||
terraformUpgrader: &stubTerraformUpgrader{},
|
||||
wantErr: true,
|
||||
yesFlag: true,
|
||||
},
|
||||
"nodeVersion in progress error": {
|
||||
upgrader: &stubUpgrader{
|
||||
kubeUpgrader: &stubKubernetesUpgrader{
|
||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
||||
nodeVersionErr: kubernetes.ErrInProgress,
|
||||
},
|
||||
yesFlag: true,
|
||||
helmUpgrader: &stubHelmUpgrader{},
|
||||
terraformUpgrader: &stubTerraformUpgrader{},
|
||||
yesFlag: true,
|
||||
},
|
||||
"helm other error": {
|
||||
upgrader: &stubUpgrader{
|
||||
kubeUpgrader: &stubKubernetesUpgrader{
|
||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
||||
helmErr: someErr,
|
||||
},
|
||||
wantErr: true,
|
||||
yesFlag: true,
|
||||
helmUpgrader: &stubHelmUpgrader{err: assert.AnError},
|
||||
terraformUpgrader: &stubTerraformUpgrader{},
|
||||
wantErr: true,
|
||||
yesFlag: true,
|
||||
},
|
||||
"check terraform error": {
|
||||
upgrader: &stubUpgrader{
|
||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
||||
checkTerraformErr: someErr,
|
||||
kubeUpgrader: &stubKubernetesUpgrader{
|
||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
||||
},
|
||||
wantErr: true,
|
||||
yesFlag: true,
|
||||
helmUpgrader: &stubHelmUpgrader{},
|
||||
terraformUpgrader: &stubTerraformUpgrader{checkTerraformErr: assert.AnError},
|
||||
wantErr: true,
|
||||
yesFlag: true,
|
||||
},
|
||||
"abort": {
|
||||
upgrader: &stubUpgrader{
|
||||
kubeUpgrader: &stubKubernetesUpgrader{
|
||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
||||
terraformDiff: true,
|
||||
},
|
||||
wantErr: true,
|
||||
stdin: "no\n",
|
||||
helmUpgrader: &stubHelmUpgrader{},
|
||||
terraformUpgrader: &stubTerraformUpgrader{terraformDiff: true},
|
||||
wantErr: true,
|
||||
stdin: "no\n",
|
||||
},
|
||||
"clean terraform error": {
|
||||
upgrader: &stubUpgrader{
|
||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
||||
cleanTerraformErr: someErr,
|
||||
kubeUpgrader: &stubKubernetesUpgrader{
|
||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
||||
},
|
||||
helmUpgrader: &stubHelmUpgrader{},
|
||||
terraformUpgrader: &stubTerraformUpgrader{
|
||||
cleanTerraformErr: assert.AnError,
|
||||
terraformDiff: true,
|
||||
},
|
||||
wantErr: true,
|
||||
stdin: "no\n",
|
||||
},
|
||||
"plan terraform error": {
|
||||
upgrader: &stubUpgrader{
|
||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
||||
planTerraformErr: someErr,
|
||||
kubeUpgrader: &stubKubernetesUpgrader{
|
||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
||||
},
|
||||
wantErr: true,
|
||||
yesFlag: true,
|
||||
helmUpgrader: &stubHelmUpgrader{},
|
||||
terraformUpgrader: &stubTerraformUpgrader{planTerraformErr: assert.AnError},
|
||||
wantErr: true,
|
||||
yesFlag: true,
|
||||
},
|
||||
"apply terraform error": {
|
||||
upgrader: &stubUpgrader{
|
||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
||||
applyTerraformErr: someErr,
|
||||
kubeUpgrader: &stubKubernetesUpgrader{
|
||||
currentConfig: config.DefaultForAzureSEVSNP(),
|
||||
},
|
||||
helmUpgrader: &stubHelmUpgrader{},
|
||||
terraformUpgrader: &stubTerraformUpgrader{
|
||||
applyTerraformErr: assert.AnError,
|
||||
terraformDiff: true,
|
||||
},
|
||||
wantErr: true,
|
||||
yesFlag: true,
|
||||
},
|
||||
"do no backup join-config when remote attestation config is the same": {
|
||||
upgrader: &stubUpgrader{
|
||||
kubeUpgrader: &stubKubernetesUpgrader{
|
||||
currentConfig: fakeAzureAttestationConfigFromCluster(context.Background(), t, cloudprovider.Azure),
|
||||
},
|
||||
helmUpgrader: &stubHelmUpgrader{},
|
||||
terraformUpgrader: &stubTerraformUpgrader{},
|
||||
yesFlag: 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.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)
|
||||
if tc.wantErr {
|
||||
@ -149,70 +175,79 @@ func TestUpgradeApply(t *testing.T) {
|
||||
return
|
||||
}
|
||||
assert.NoError(err)
|
||||
assert.Equal(!tc.dontWantJoinConfigBackup, tc.upgrader.backupWasCalled)
|
||||
assert.Equal(!tc.dontWantJoinConfigBackup, tc.kubeUpgrader.backupWasCalled)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type stubUpgrader struct {
|
||||
currentConfig config.AttestationCfg
|
||||
nodeVersionErr error
|
||||
helmErr error
|
||||
type stubHelmUpgrader struct {
|
||||
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
|
||||
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
|
||||
planTerraformErr error
|
||||
checkTerraformErr error
|
||||
applyTerraformErr error
|
||||
cleanTerraformErr error
|
||||
backupWasCalled bool
|
||||
}
|
||||
|
||||
func (u stubUpgrader) GetMeasurementSalt(_ context.Context) ([]byte, 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 {
|
||||
func (u stubTerraformUpgrader) CheckTerraformMigrations(_ string) error {
|
||||
return u.checkTerraformErr
|
||||
}
|
||||
|
||||
func (u stubUpgrader) CleanUpTerraformMigrations(_ string) error {
|
||||
func (u stubTerraformUpgrader) CleanUpTerraformMigrations(_ string) error {
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func (u stubUpgrader) ExtendClusterConfigCertSANs(_ context.Context, _ []string) error {
|
||||
return nil
|
||||
func (u stubTerraformUpgrader) UpgradeID() string {
|
||||
return "test-upgrade"
|
||||
}
|
||||
|
||||
func fakeAzureAttestationConfigFromCluster(ctx context.Context, t *testing.T, provider cloudprovider.Provider) config.AttestationCfg {
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
@ -71,11 +72,14 @@ func runUpgradeCheck(cmd *cobra.Command, _ []string) error {
|
||||
}
|
||||
|
||||
fileHandler := file.NewHandler(afero.NewOsFs())
|
||||
checker, err := kubernetes.NewUpgrader(
|
||||
cmd.Context(), cmd.OutOrStdout(),
|
||||
constants.UpgradeDir, constants.AdminConfFilename,
|
||||
fileHandler, log, kubernetes.UpgradeCmdKindCheck,
|
||||
)
|
||||
upgradeID := generateUpgradeID(upgradeCmdKindCheck)
|
||||
|
||||
tfClient, err := terraform.New(cmd.Context(), filepath.Join(constants.UpgradeDir, upgradeID, constants.TerraformUpgradeWorkingDir))
|
||||
if err != nil {
|
||||
return fmt.Errorf("setting up terraform client: %w", err)
|
||||
}
|
||||
|
||||
kubeChecker, err := kubernetes.NewUpgrader(cmd.OutOrStdout(), constants.AdminConfFilename, log)
|
||||
if err != nil {
|
||||
return fmt.Errorf("setting up Kubernetes upgrader: %w", err)
|
||||
}
|
||||
@ -89,7 +93,7 @@ func runUpgradeCheck(cmd *cobra.Command, _ []string) error {
|
||||
canUpgradeCheck: featureset.CanUpgradeCheck,
|
||||
collect: &versionCollector{
|
||||
writer: cmd.OutOrStderr(),
|
||||
checker: checker,
|
||||
kubeChecker: kubeChecker,
|
||||
verListFetcher: versionfetcher,
|
||||
fileHandler: fileHandler,
|
||||
client: http.DefaultClient,
|
||||
@ -99,8 +103,8 @@ func runUpgradeCheck(cmd *cobra.Command, _ []string) error {
|
||||
log: log,
|
||||
versionsapi: versionfetcher,
|
||||
},
|
||||
checker: checker,
|
||||
log: log,
|
||||
terraformChecker: upgrade.NewTerraformUpgrader(tfClient, cmd.OutOrStdout(), fileHandler, upgradeID),
|
||||
log: log,
|
||||
}
|
||||
|
||||
return up.upgradeCheck(cmd, fileHandler, attestationconfigapi.NewFetcher(), flags)
|
||||
@ -143,10 +147,10 @@ func parseUpgradeCheckFlags(cmd *cobra.Command) (upgradeCheckFlags, error) {
|
||||
}
|
||||
|
||||
type upgradeCheckCmd struct {
|
||||
canUpgradeCheck bool
|
||||
collect collector
|
||||
checker upgradeChecker
|
||||
log debugLog
|
||||
canUpgradeCheck bool
|
||||
collect collector
|
||||
terraformChecker terraformChecker
|
||||
log debugLog
|
||||
}
|
||||
|
||||
// upgradePlan plans an upgrade of a Constellation cluster.
|
||||
@ -212,7 +216,7 @@ func (u *upgradeCheckCmd) upgradeCheck(cmd *cobra.Command, fileHandler file.Hand
|
||||
// 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)
|
||||
}
|
||||
|
||||
@ -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:")
|
||||
|
||||
// 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 {
|
||||
return fmt.Errorf("planning terraform migrations: %w", err)
|
||||
}
|
||||
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)
|
||||
}
|
||||
}()
|
||||
@ -323,7 +327,7 @@ type collector interface {
|
||||
|
||||
type versionCollector struct {
|
||||
writer io.Writer
|
||||
checker upgradeChecker
|
||||
kubeChecker kubernetesChecker
|
||||
verListFetcher versionListFetcher
|
||||
fileHandler file.Handler
|
||||
client *http.Client
|
||||
@ -382,12 +386,12 @@ func (v *versionCollector) currentVersions(ctx context.Context) (currentVersionI
|
||||
return currentVersionInfo{}, fmt.Errorf("getting service versions: %w", err)
|
||||
}
|
||||
|
||||
imageVersion, err := getCurrentImageVersion(ctx, v.checker)
|
||||
imageVersion, err := getCurrentImageVersion(ctx, v.kubeChecker)
|
||||
if err != nil {
|
||||
return currentVersionInfo{}, fmt.Errorf("getting image version: %w", err)
|
||||
}
|
||||
|
||||
k8sVersion, err := getCurrentKubernetesVersion(ctx, v.checker)
|
||||
k8sVersion, err := getCurrentKubernetesVersion(ctx, v.kubeChecker)
|
||||
if err != nil {
|
||||
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.
|
||||
// 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)
|
||||
if err != nil {
|
||||
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.
|
||||
func getCurrentKubernetesVersion(ctx context.Context, checker upgradeChecker) (string, error) {
|
||||
func getCurrentKubernetesVersion(ctx context.Context, checker kubernetesChecker) (string, error) {
|
||||
k8sVersion, err := checker.CurrentKubernetesVersion(ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@ -745,9 +749,12 @@ type upgradeCheckFlags struct {
|
||||
terraformLogLevel terraform.LogLevel
|
||||
}
|
||||
|
||||
type upgradeChecker interface {
|
||||
type kubernetesChecker interface {
|
||||
CurrentImage(ctx context.Context) (string, error)
|
||||
CurrentKubernetesVersion(ctx context.Context) (string, error)
|
||||
}
|
||||
|
||||
type terraformChecker interface {
|
||||
PlanTerraformMigrations(ctx context.Context, opts upgrade.TerraformUpgradeOptions) (bool, error)
|
||||
CheckTerraformMigrations(upgradeWorkspace string) error
|
||||
CleanUpTerraformMigrations(upgradeWorkspace string) error
|
||||
|
@ -110,22 +110,22 @@ func TestBuildString(t *testing.T) {
|
||||
|
||||
func TestGetCurrentImageVersion(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
stubUpgradeChecker stubUpgradeChecker
|
||||
wantErr bool
|
||||
stubKubernetesChecker stubKubernetesChecker
|
||||
wantErr bool
|
||||
}{
|
||||
"valid version": {
|
||||
stubUpgradeChecker: stubUpgradeChecker{
|
||||
stubKubernetesChecker: stubKubernetesChecker{
|
||||
image: "v1.0.0",
|
||||
},
|
||||
},
|
||||
"invalid version": {
|
||||
stubUpgradeChecker: stubUpgradeChecker{
|
||||
stubKubernetesChecker: stubKubernetesChecker{
|
||||
image: "invalid",
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
"GetCurrentImage error": {
|
||||
stubUpgradeChecker: stubUpgradeChecker{
|
||||
stubKubernetesChecker: stubKubernetesChecker{
|
||||
err: errors.New("error"),
|
||||
},
|
||||
wantErr: true,
|
||||
@ -136,7 +136,7 @@ func TestGetCurrentImageVersion(t *testing.T) {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
version, err := getCurrentImageVersion(context.Background(), tc.stubUpgradeChecker)
|
||||
version, err := getCurrentImageVersion(context.Background(), tc.stubKubernetesChecker)
|
||||
if tc.wantErr {
|
||||
assert.Error(err)
|
||||
return
|
||||
@ -215,19 +215,19 @@ func TestUpgradeCheck(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
collector stubVersionCollector
|
||||
csp cloudprovider.Provider
|
||||
checker stubUpgradeChecker
|
||||
checker stubTerraformChecker
|
||||
cliVersion string
|
||||
wantError bool
|
||||
}{
|
||||
"upgrades gcp": {
|
||||
collector: collector,
|
||||
checker: stubUpgradeChecker{},
|
||||
checker: stubTerraformChecker{},
|
||||
csp: cloudprovider.GCP,
|
||||
cliVersion: "v1.0.0",
|
||||
},
|
||||
"terraform err": {
|
||||
collector: collector,
|
||||
checker: stubUpgradeChecker{
|
||||
checker: stubTerraformChecker{
|
||||
err: assert.AnError,
|
||||
},
|
||||
csp: cloudprovider.GCP,
|
||||
@ -245,10 +245,10 @@ func TestUpgradeCheck(t *testing.T) {
|
||||
require.NoError(fileHandler.WriteYAML(constants.ConfigFilename, cfg))
|
||||
|
||||
checkCmd := upgradeCheckCmd{
|
||||
canUpgradeCheck: true,
|
||||
collect: &tc.collector,
|
||||
checker: tc.checker,
|
||||
log: logger.NewTest(t),
|
||||
canUpgradeCheck: true,
|
||||
collect: &tc.collector,
|
||||
terraformChecker: tc.checker,
|
||||
log: logger.NewTest(t),
|
||||
}
|
||||
|
||||
cmd := newUpgradeCheckCmd()
|
||||
@ -317,31 +317,35 @@ func (s *stubVersionCollector) filterCompatibleCLIVersions(_ context.Context, _
|
||||
return s.newCompatibleCLIVersionsList, nil
|
||||
}
|
||||
|
||||
type stubUpgradeChecker struct {
|
||||
type stubKubernetesChecker struct {
|
||||
image string
|
||||
k8sVersion string
|
||||
tfDiff bool
|
||||
err error
|
||||
}
|
||||
|
||||
func (u stubUpgradeChecker) CurrentImage(context.Context) (string, error) {
|
||||
return u.image, u.err
|
||||
func (s stubKubernetesChecker) CurrentImage(context.Context) (string, error) {
|
||||
return s.image, s.err
|
||||
}
|
||||
|
||||
func (u stubUpgradeChecker) CurrentKubernetesVersion(context.Context) (string, error) {
|
||||
return u.k8sVersion, u.err
|
||||
func (s stubKubernetesChecker) CurrentKubernetesVersion(context.Context) (string, error) {
|
||||
return s.k8sVersion, s.err
|
||||
}
|
||||
|
||||
func (u stubUpgradeChecker) PlanTerraformMigrations(context.Context, upgrade.TerraformUpgradeOptions) (bool, error) {
|
||||
return u.tfDiff, u.err
|
||||
type stubTerraformChecker struct {
|
||||
tfDiff bool
|
||||
err error
|
||||
}
|
||||
|
||||
func (u stubUpgradeChecker) CheckTerraformMigrations(_ string) error {
|
||||
return u.err
|
||||
func (s stubTerraformChecker) PlanTerraformMigrations(context.Context, upgrade.TerraformUpgradeOptions) (bool, error) {
|
||||
return s.tfDiff, s.err
|
||||
}
|
||||
|
||||
func (u stubUpgradeChecker) CleanUpTerraformMigrations(_ string) error {
|
||||
return u.err
|
||||
func (s stubTerraformChecker) CheckTerraformMigrations(_ string) error {
|
||||
return s.err
|
||||
}
|
||||
|
||||
func (s stubTerraformChecker) CleanUpTerraformMigrations(_ string) error {
|
||||
return s.err
|
||||
}
|
||||
|
||||
func TestNewCLIVersions(t *testing.T) {
|
||||
|
@ -11,25 +11,17 @@ go_library(
|
||||
importpath = "github.com/edgelesssys/constellation/v2/cli/internal/kubernetes",
|
||||
visibility = ["//cli:__subpackages__"],
|
||||
deps = [
|
||||
"//cli/internal/clusterid",
|
||||
"//cli/internal/helm",
|
||||
"//cli/internal/terraform",
|
||||
"//cli/internal/upgrade",
|
||||
"//internal/api/versionsapi",
|
||||
"//internal/attestation/variant",
|
||||
"//internal/cloud/cloudprovider",
|
||||
"//internal/compatibility",
|
||||
"//internal/config",
|
||||
"//internal/constants",
|
||||
"//internal/file",
|
||||
"//internal/imagefetcher",
|
||||
"//internal/kms/uri",
|
||||
"//internal/kubernetes",
|
||||
"//internal/kubernetes/kubectl",
|
||||
"//internal/versions",
|
||||
"//internal/versions/components",
|
||||
"//operators/constellation-node-operator/api/v1alpha1",
|
||||
"@com_github_google_uuid//:uuid",
|
||||
"@io_k8s_api//core/v1:core",
|
||||
"@io_k8s_apimachinery//pkg/api/errors",
|
||||
"@io_k8s_apimachinery//pkg/apis/meta/v1:meta",
|
||||
|
@ -12,30 +12,20 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"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/attestation/variant"
|
||||
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
||||
"github.com/edgelesssys/constellation/v2/internal/compatibility"
|
||||
"github.com/edgelesssys/constellation/v2/internal/config"
|
||||
"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/kms/uri"
|
||||
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/components"
|
||||
updatev1alpha1 "github.com/edgelesssys/constellation/v2/operators/constellation-node-operator/v2/api/v1alpha1"
|
||||
"github.com/google/uuid"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
k8serrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@ -49,16 +39,6 @@ import (
|
||||
"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.
|
||||
var ErrInProgress = errors.New("upgrade in progress")
|
||||
|
||||
@ -91,69 +71,36 @@ func (e *applyError) Error() string {
|
||||
type Upgrader struct {
|
||||
stableInterface StableInterface
|
||||
dynamicInterface DynamicInterface
|
||||
helmClient helmInterface
|
||||
imageFetcher imageFetcher
|
||||
outWriter io.Writer
|
||||
tfUpgrader *upgrade.TerraformUpgrader
|
||||
log debugLog
|
||||
upgradeID string
|
||||
}
|
||||
|
||||
// NewUpgrader returns a new Upgrader.
|
||||
func NewUpgrader(
|
||||
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,
|
||||
}
|
||||
|
||||
func NewUpgrader(outWriter io.Writer, kubeConfigPath string, log debugLog) (*Upgrader, error) {
|
||||
kubeClient, err := newClient(kubeConfigPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u.stableInterface = &stableClient{client: kubeClient}
|
||||
|
||||
// use unstructured client to avoid importing the operator packages
|
||||
kubeConfig, err := clientcmd.BuildConfigFromFlags("", kubeConfigPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("building kubernetes config: %w", err)
|
||||
}
|
||||
|
||||
unstructuredClient, err := dynamic.NewForConfig(kubeConfig)
|
||||
if err != nil {
|
||||
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)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("setting up helm client: %w", err)
|
||||
}
|
||||
u.helmClient = helmClient
|
||||
|
||||
tfClient, err := terraform.New(ctx, filepath.Join(upgradeWorkspace, upgradeID, constants.TerraformUpgradeWorkingDir))
|
||||
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
|
||||
return &Upgrader{
|
||||
imageFetcher: imagefetcher.New(),
|
||||
outWriter: outWriter,
|
||||
log: log,
|
||||
stableInterface: &stableClient{client: kubeClient},
|
||||
dynamicInterface: &NodeVersionClient{client: unstructuredClient},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetMeasurementSalt returns the measurementSalt from the join-config.
|
||||
@ -169,47 +116,6 @@ func (u *Upgrader) GetMeasurementSalt(ctx context.Context) ([]byte, error) {
|
||||
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.
|
||||
// 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 {
|
||||
@ -569,10 +475,6 @@ func upgradeInProgress(nodeVersion updatev1alpha1.NodeVersion) bool {
|
||||
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 {
|
||||
Debugf(format string, args ...any)
|
||||
Sync()
|
||||
|
@ -21,24 +21,6 @@ import (
|
||||
"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.
|
||||
type TerraformUpgradeOptions struct {
|
||||
// LogLevel is the log level used for Terraform.
|
||||
@ -51,55 +33,43 @@ type TerraformUpgradeOptions struct {
|
||||
UpgradeWorkspace string
|
||||
}
|
||||
|
||||
// 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),
|
||||
}
|
||||
// TerraformUpgrader is responsible for performing Terraform migrations on cluster upgrades.
|
||||
type TerraformUpgrader struct {
|
||||
tf tfResourceClient
|
||||
policyPatcher policyPatcher
|
||||
outWriter io.Writer
|
||||
fileHandler file.Handler
|
||||
upgradeID string
|
||||
}
|
||||
|
||||
for _, f := range filesToCheck {
|
||||
if err := checkFileExists(file, &existingFiles, f); err != nil {
|
||||
return fmt.Errorf("checking terraform migrations: %w", err)
|
||||
}
|
||||
// NewTerraformUpgrader returns a new TerraformUpgrader.
|
||||
func NewTerraformUpgrader(tfClient tfResourceClient, outWriter io.Writer, fileHandler file.Handler, upgradeID string,
|
||||
) *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.
|
||||
// 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 {
|
||||
return checkTerraformMigrations(u.fileHandler, upgradeWorkspace, upgradeID, upgradeSubDir)
|
||||
}
|
||||
|
||||
// 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
|
||||
func (u *TerraformUpgrader) CheckTerraformMigrations(upgradeWorkspace string) error {
|
||||
return checkTerraformMigrations(u.fileHandler, upgradeWorkspace, u.upgradeID, constants.TerraformUpgradeBackupDir)
|
||||
}
|
||||
|
||||
// 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 *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
|
||||
err := u.tf.PrepareUpgradeWorkspace(
|
||||
filepath.Join("terraform", strings.ToLower(opts.CSP.String())),
|
||||
opts.TFWorkspace,
|
||||
filepath.Join(opts.UpgradeWorkspace, upgradeID, constants.TerraformUpgradeWorkingDir),
|
||||
filepath.Join(opts.UpgradeWorkspace, upgradeID, constants.TerraformUpgradeBackupDir),
|
||||
filepath.Join(opts.UpgradeWorkspace, u.upgradeID, constants.TerraformUpgradeWorkingDir),
|
||||
filepath.Join(opts.UpgradeWorkspace, u.upgradeID, constants.TerraformUpgradeBackupDir),
|
||||
opts.Vars,
|
||||
)
|
||||
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
|
||||
// aborted by the user.
|
||||
func (u *TerraformUpgrader) CleanUpTerraformMigrations(upgradeWorkspace, upgradeID string) error {
|
||||
return CleanUpTerraformMigrations(upgradeWorkspace, 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
|
||||
func (u *TerraformUpgrader) CleanUpTerraformMigrations(upgradeWorkspace string) error {
|
||||
return CleanUpTerraformMigrations(upgradeWorkspace, u.upgradeID, u.fileHandler)
|
||||
}
|
||||
|
||||
// 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 *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)
|
||||
if err != nil {
|
||||
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(
|
||||
filepath.Join(opts.UpgradeWorkspace, upgradeID, constants.TerraformUpgradeWorkingDir),
|
||||
filepath.Join(opts.UpgradeWorkspace, u.upgradeID, constants.TerraformUpgradeWorkingDir),
|
||||
opts.TFWorkspace,
|
||||
); err != nil {
|
||||
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, 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 {
|
||||
ShowPlan(ctx context.Context, logLevel terraform.LogLevel, output io.Writer) error
|
||||
Plan(ctx context.Context, logLevel terraform.LogLevel) (bool, error)
|
||||
|
@ -23,13 +23,6 @@ import (
|
||||
)
|
||||
|
||||
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 {
|
||||
fs := afero.NewMemMapFs()
|
||||
for _, f := range existingFiles {
|
||||
@ -57,8 +50,9 @@ func TestCheckTerraformMigrations(t *testing.T) {
|
||||
|
||||
for name, tc := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
u := upgrader(tc.workspace)
|
||||
err := u.CheckTerraformMigrations(constants.UpgradeDir, tc.upgradeID, constants.TerraformUpgradeBackupDir)
|
||||
u := NewTerraformUpgrader(&stubTerraformClient{}, bytes.NewBuffer(nil), tc.workspace, tc.upgradeID)
|
||||
|
||||
err := u.CheckTerraformMigrations(constants.UpgradeDir)
|
||||
if tc.wantErr {
|
||||
require.Error(t, err)
|
||||
return
|
||||
@ -70,12 +64,6 @@ func TestCheckTerraformMigrations(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 {
|
||||
fs := afero.NewMemMapFs()
|
||||
for _, f := range existingFiles {
|
||||
@ -142,7 +130,7 @@ func TestPlanTerraformMigrations(t *testing.T) {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
u := upgrader(tc.tf, tc.workspace)
|
||||
u := NewTerraformUpgrader(tc.tf, bytes.NewBuffer(nil), tc.workspace, tc.upgradeID)
|
||||
|
||||
opts := TerraformUpgradeOptions{
|
||||
LogLevel: terraform.LogLevelDebug,
|
||||
@ -150,7 +138,7 @@ func TestPlanTerraformMigrations(t *testing.T) {
|
||||
Vars: &terraform.QEMUVariables{},
|
||||
}
|
||||
|
||||
diff, err := u.PlanTerraformMigrations(context.Background(), opts, tc.upgradeID)
|
||||
diff, err := u.PlanTerraformMigrations(context.Background(), opts)
|
||||
if tc.wantErr {
|
||||
require.Error(err)
|
||||
} else {
|
||||
@ -162,13 +150,6 @@ func TestPlanTerraformMigrations(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 {
|
||||
fh := file.NewHandler(afero.NewMemMapFs())
|
||||
|
||||
@ -211,7 +192,7 @@ func TestApplyTerraformMigrations(t *testing.T) {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
u := upgrader(tc.tf, tc.fs)
|
||||
u := NewTerraformUpgrader(tc.tf, bytes.NewBuffer(nil), tc.fs, tc.upgradeID)
|
||||
|
||||
opts := TerraformUpgradeOptions{
|
||||
LogLevel: terraform.LogLevelDebug,
|
||||
@ -221,7 +202,7 @@ func TestApplyTerraformMigrations(t *testing.T) {
|
||||
UpgradeWorkspace: constants.UpgradeDir,
|
||||
}
|
||||
|
||||
_, err := u.ApplyTerraformMigrations(context.Background(), opts, tc.upgradeID)
|
||||
_, err := u.ApplyTerraformMigrations(context.Background(), opts)
|
||||
if tc.wantErr {
|
||||
require.Error(err)
|
||||
} else {
|
||||
@ -232,13 +213,6 @@ func TestApplyTerraformMigrations(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 {
|
||||
fs := afero.NewMemMapFs()
|
||||
for _, f := range existingFiles {
|
||||
@ -299,9 +273,9 @@ func TestCleanUpTerraformMigrations(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
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 {
|
||||
require.Error(err)
|
||||
return
|
||||
|
Loading…
Reference in New Issue
Block a user