mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-08-07 06:22:17 -04:00
cli: common backend for init
and upgrade apply
commands (#2449)
* Use common 'apply' backend for init and upgrades * Move unit tests to new apply backend * Only perform Terraform migrations if state exists in cwd (#2457) * Rework skipPhases logic --------- Signed-off-by: Daniel Weiße <dw@edgeless.systems> Co-authored-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>
This commit is contained in:
parent
15d249092c
commit
671cf36f0a
15 changed files with 1399 additions and 1018 deletions
125
cli/internal/cmd/applyhelm.go
Normal file
125
cli/internal/cmd/applyhelm.go
Normal file
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
Copyright (c) Edgeless Systems GmbH
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/edgelesssys/constellation/v2/cli/internal/cloudcmd"
|
||||
"github.com/edgelesssys/constellation/v2/cli/internal/helm"
|
||||
"github.com/edgelesssys/constellation/v2/cli/internal/state"
|
||||
"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/kms/uri"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// runHelmApply handles installing or upgrading helm charts for the cluster.
|
||||
func (a *applyCmd) runHelmApply(
|
||||
cmd *cobra.Command, conf *config.Config, stateFile *state.State,
|
||||
kubeUpgrader kubernetesUpgrader, upgradeDir string,
|
||||
) error {
|
||||
a.log.Debugf("Installing or upgrading Helm charts")
|
||||
var masterSecret uri.MasterSecret
|
||||
if err := a.fileHandler.ReadJSON(constants.MasterSecretFilename, &masterSecret); err != nil {
|
||||
return fmt.Errorf("reading master secret: %w", err)
|
||||
}
|
||||
|
||||
options := helm.Options{
|
||||
Force: a.flags.force,
|
||||
Conformance: a.flags.conformance,
|
||||
HelmWaitMode: a.flags.helmWaitMode,
|
||||
AllowDestructive: helm.DenyDestructive,
|
||||
}
|
||||
helmApplier, err := a.newHelmClient(constants.AdminConfFilename, a.log)
|
||||
if err != nil {
|
||||
return fmt.Errorf("creating Helm client: %w", err)
|
||||
}
|
||||
|
||||
a.log.Debugf("Getting service account URI")
|
||||
serviceAccURI, err := cloudcmd.GetMarshaledServiceAccountURI(conf, a.fileHandler)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
a.log.Debugf("Preparing Helm charts")
|
||||
executor, includesUpgrades, err := helmApplier.PrepareApply(conf, stateFile, options, serviceAccURI, masterSecret)
|
||||
if errors.Is(err, helm.ErrConfirmationMissing) {
|
||||
if !a.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.")
|
||||
ok, askErr := askToConfirm(cmd, "Do you want to upgrade cert-manager anyway?")
|
||||
if askErr != nil {
|
||||
return fmt.Errorf("asking for confirmation: %w", err)
|
||||
}
|
||||
if !ok {
|
||||
cmd.Println("Skipping upgrade.")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
options.AllowDestructive = helm.AllowDestructive
|
||||
executor, includesUpgrades, err = helmApplier.PrepareApply(conf, stateFile, options, serviceAccURI, masterSecret)
|
||||
}
|
||||
var upgradeErr *compatibility.InvalidUpgradeError
|
||||
if err != nil {
|
||||
if !errors.As(err, &upgradeErr) {
|
||||
return fmt.Errorf("preparing Helm charts: %w", err)
|
||||
}
|
||||
cmd.PrintErrln(err)
|
||||
}
|
||||
|
||||
a.log.Debugf("Backing up Helm charts")
|
||||
if err := a.backupHelmCharts(cmd.Context(), kubeUpgrader, executor, includesUpgrades, upgradeDir); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
a.log.Debugf("Applying Helm charts")
|
||||
if !a.flags.skipPhases.contains(skipInitPhase) {
|
||||
a.spinner.Start("Installing Kubernetes components ", false)
|
||||
} else {
|
||||
a.spinner.Start("Upgrading Kubernetes components ", false)
|
||||
}
|
||||
|
||||
if err := executor.Apply(cmd.Context()); err != nil {
|
||||
return fmt.Errorf("applying Helm charts: %w", err)
|
||||
}
|
||||
a.spinner.Stop()
|
||||
|
||||
if a.flags.skipPhases.contains(skipInitPhase) {
|
||||
cmd.Println("Successfully upgraded Constellation services.")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// backupHelmCharts saves the Helm charts for the upgrade to disk and creates a backup of existing CRDs and CRs.
|
||||
func (a *applyCmd) backupHelmCharts(
|
||||
ctx context.Context, kubeUpgrader kubernetesUpgrader, executor helm.Applier, includesUpgrades bool, upgradeDir string,
|
||||
) error {
|
||||
// Save the Helm charts for the upgrade to disk
|
||||
chartDir := filepath.Join(upgradeDir, "helm-charts")
|
||||
if err := executor.SaveCharts(chartDir, a.fileHandler); err != nil {
|
||||
return fmt.Errorf("saving Helm charts to disk: %w", err)
|
||||
}
|
||||
a.log.Debugf("Helm charts saved to %s", a.flags.pathPrefixer.PrefixPrintablePath(chartDir))
|
||||
|
||||
if includesUpgrades {
|
||||
a.log.Debugf("Creating backup of CRDs and CRs")
|
||||
crds, err := kubeUpgrader.BackupCRDs(ctx, upgradeDir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("creating CRD backup: %w", err)
|
||||
}
|
||||
if err := kubeUpgrader.BackupCRs(ctx, crds, upgradeDir); err != nil {
|
||||
return fmt.Errorf("creating CR backup: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue