Skip to content

Commit

Permalink
rename "node" to "image" and skip k8sPhase correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
elchead committed Sep 8, 2023
1 parent ace41a7 commit c180014
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 45 deletions.
16 changes: 9 additions & 7 deletions cli/internal/cmd/upgradeapply.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ const (
skipInfrastructurePhase skipPhase = "infrastructure"
// skipHelmPhase skips the helm upgrade of the upgrade process.
skipHelmPhase skipPhase = "helm"
// skipNodePhase skips the node upgrade of the upgrade process.
skipNodePhase skipPhase = "node"
// skipImagePhase skips the image upgrade of the upgrade process.
skipImagePhase skipPhase = "image"
// skipK8sPhase skips the k8s upgrade of the upgrade process.
skipK8sPhase skipPhase = "k8s"
)
Expand All @@ -69,7 +69,7 @@ func newUpgradeApplyCmd() *cobra.Command {
cmd.Flags().Bool("conformance", false, "enable conformance mode")
cmd.Flags().Bool("skip-helm-wait", false, "install helm charts without waiting for deployments to be ready")
cmd.Flags().StringSlice("skip-phases", nil, "comma-separated list of upgrade phases to skip\n"+
"one or multiple of { infrastructure | helm | node | k8s }")
"one or multiple of { infrastructure | helm | image | k8s }")
if err := cmd.Flags().MarkHidden("timeout"); err != nil {
panic(err)
}
Expand Down Expand Up @@ -234,8 +234,10 @@ func (u *upgradeApplyCmd) upgradeApply(cmd *cobra.Command, upgradeDir string, fl
}
}

if !flags.skipPhases.contains(skipNodePhase) {
err = u.kubeUpgrader.UpgradeNodeVersion(cmd.Context(), conf, flags.force)
skipImageUpgrade := flags.skipPhases.contains(skipImagePhase)
skipK8sUpgrade := flags.skipPhases.contains(skipK8sPhase)
if !(skipImageUpgrade && skipK8sUpgrade) {
err = u.kubeUpgrader.UpgradeNodeVersion(cmd.Context(), conf, flags.force, skipImageUpgrade, skipK8sUpgrade)
switch {
case errors.Is(err, kubecmd.ErrInProgress):
cmd.PrintErrln("Skipping image and Kubernetes upgrades. Another upgrade is in progress.")
Expand Down Expand Up @@ -552,7 +554,7 @@ func parseUpgradeApplyFlags(cmd *cobra.Command) (upgradeApplyFlags, error) {
var skipPhases []skipPhase
for _, phase := range rawSkipPhases {
switch skipPhase(phase) {
case skipInfrastructurePhase, skipHelmPhase, skipNodePhase, skipK8sPhase:
case skipInfrastructurePhase, skipHelmPhase, skipImagePhase, skipK8sPhase:
skipPhases = append(skipPhases, skipPhase(phase))
default:
return upgradeApplyFlags{}, fmt.Errorf("invalid phase %s", phase)
Expand Down Expand Up @@ -619,7 +621,7 @@ func (s skipPhases) contains(phase skipPhase) bool {
}

type kubernetesUpgrader interface {
UpgradeNodeVersion(ctx context.Context, conf *config.Config, force bool) error
UpgradeNodeVersion(ctx context.Context, conf *config.Config, force, skipImage, skipK8s bool) error
ExtendClusterConfigCertSANs(ctx context.Context, alternativeNames []string) error
GetClusterAttestationConfig(ctx context.Context, variant variant.Variant) (config.AttestationCfg, error)
ApplyJoinConfig(ctx context.Context, newAttestConfig config.AttestationCfg, measurementSalt []byte) error
Expand Down
8 changes: 4 additions & 4 deletions cli/internal/cmd/upgradeapply_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ func TestUpgradeApply(t *testing.T) {
helmUpgrader: &mockApplier{}, // mocks ensure that no methods are called
terraformUpgrader: &mockTerraformUpgrader{},
flags: upgradeApplyFlags{
skipPhases: []skipPhase{skipInfrastructurePhase, skipHelmPhase, skipK8sPhase, skipNodePhase},
skipPhases: []skipPhase{skipInfrastructurePhase, skipHelmPhase, skipK8sPhase, skipImagePhase},
yes: true,
},
},
Expand Down Expand Up @@ -159,7 +159,7 @@ func TestUpgradeApply(t *testing.T) {
return
}
assert.NoError(err)
assert.Equal(!tc.flags.skipPhases.contains(skipNodePhase), tc.kubeUpgrader.calledNodeUpgrade,
assert.Equal(!tc.flags.skipPhases.contains(skipImagePhase), tc.kubeUpgrader.calledNodeUpgrade,
"incorrect node upgrade skipping behavior")
})
}
Expand All @@ -175,7 +175,7 @@ func TestUpgradeApplyFlagsForSkipPhases(t *testing.T) {
if err != nil {
t.Fatalf("Error while parsing flags: %v", err)
}
assert.ElementsMatch(t, []skipPhase{skipInfrastructurePhase, skipHelmPhase, skipK8sPhase, skipNodePhase}, result.skipPhases)
assert.ElementsMatch(t, []skipPhase{skipInfrastructurePhase, skipHelmPhase, skipK8sPhase, skipImagePhase}, result.skipPhases)
}

type stubKubernetesUpgrader struct {
Expand All @@ -192,7 +192,7 @@ func (u *stubKubernetesUpgrader) BackupCRs(_ context.Context, _ []apiextensionsv
return nil
}

func (u *stubKubernetesUpgrader) UpgradeNodeVersion(_ context.Context, _ *config.Config, _ bool) error {
func (u *stubKubernetesUpgrader) UpgradeNodeVersion(_ context.Context, _ *config.Config, _, _, _ bool) error {
u.calledNodeUpgrade = true
return u.nodeVersionErr
}
Expand Down
66 changes: 35 additions & 31 deletions cli/internal/kubecmd/kubecmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ func New(outWriter io.Writer, kubeConfigPath string, fileHandler file.Handler, l

// 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 (k *KubeCmd) UpgradeNodeVersion(ctx context.Context, conf *config.Config, force bool) error {
// TODO(elchead): AB#3434 Split K8s and image upgrade of UpgradeNodeVersion.
func (k *KubeCmd) UpgradeNodeVersion(ctx context.Context, conf *config.Config, force, skipImage, skipK8s bool) error {
provider := conf.GetProvider()
attestationVariant := conf.GetAttestationConfig().GetVariant()
region := conf.GetRegion()
Expand All @@ -120,40 +121,43 @@ func (k *KubeCmd) UpgradeNodeVersion(ctx context.Context, conf *config.Config, f

upgradeErrs := []error{}
var upgradeErr *compatibility.InvalidUpgradeError

err = k.isValidImageUpgrade(nodeVersion, imageVersion.Version(), force)
switch {
case errors.As(err, &upgradeErr):
upgradeErrs = append(upgradeErrs, fmt.Errorf("skipping image upgrades: %w", err))
case err != nil:
return fmt.Errorf("updating image version: %w", err)
}
k.log.Debugf("Updating local copy of nodeVersion image version from %s to %s", nodeVersion.Spec.ImageVersion, imageVersion.Version())
nodeVersion.Spec.ImageReference = imageReference
nodeVersion.Spec.ImageVersion = imageVersion.Version()

// We have to allow users to specify outdated k8s patch versions.
// Therefore, this code has to skip k8s updates if a user configures an outdated (i.e. invalid) k8s version.
var components *corev1.ConfigMap
currentK8sVersion, err := versions.NewValidK8sVersion(conf.KubernetesVersion, true)
if err != nil {
innerErr := fmt.Errorf("unsupported Kubernetes version, supported versions are %s", strings.Join(versions.SupportedK8sVersions(), ", "))
err = compatibility.NewInvalidUpgradeError(nodeVersion.Spec.KubernetesClusterVersion, conf.KubernetesVersion, innerErr)
} else {
versionConfig := versions.VersionConfigs[currentK8sVersion]
components, err = k.updateK8s(&nodeVersion, versionConfig.ClusterVersion, versionConfig.KubernetesComponents, force)
if !skipImage {
err = k.isValidImageUpgrade(nodeVersion, imageVersion.Version(), force)
switch {
case errors.As(err, &upgradeErr):
upgradeErrs = append(upgradeErrs, fmt.Errorf("skipping image upgrades: %w", err))
case err != nil:
return fmt.Errorf("updating image version: %w", err)
}
k.log.Debugf("Updating local copy of nodeVersion image version from %s to %s", nodeVersion.Spec.ImageVersion, imageVersion.Version())
nodeVersion.Spec.ImageReference = imageReference
nodeVersion.Spec.ImageVersion = imageVersion.Version()
}

switch {
case err == nil:
err := k.applyComponentsCM(ctx, components)
if !skipK8s {
// We have to allow users to specify outdated k8s patch versions.
// Therefore, this code has to skip k8s updates if a user configures an outdated (i.e. invalid) k8s version.
var components *corev1.ConfigMap
currentK8sVersion, err := versions.NewValidK8sVersion(conf.KubernetesVersion, true)
if err != nil {
return fmt.Errorf("applying k8s components ConfigMap: %w", err)
innerErr := fmt.Errorf("unsupported Kubernetes version, supported versions are %s", strings.Join(versions.SupportedK8sVersions(), ", "))
err = compatibility.NewInvalidUpgradeError(nodeVersion.Spec.KubernetesClusterVersion, conf.KubernetesVersion, innerErr)
} else {
versionConfig := versions.VersionConfigs[currentK8sVersion]
components, err = k.updateK8s(&nodeVersion, versionConfig.ClusterVersion, versionConfig.KubernetesComponents, force)
}

switch {
case err == nil:
err := k.applyComponentsCM(ctx, components)
if err != nil {
return fmt.Errorf("applying k8s components ConfigMap: %w", err)
}
case errors.As(err, &upgradeErr):
upgradeErrs = append(upgradeErrs, fmt.Errorf("skipping Kubernetes upgrades: %w", err))
default:
return fmt.Errorf("updating Kubernetes version: %w", err)
}
case errors.As(err, &upgradeErr):
upgradeErrs = append(upgradeErrs, fmt.Errorf("skipping Kubernetes upgrades: %w", err))
default:
return fmt.Errorf("updating Kubernetes version: %w", err)
}

if len(upgradeErrs) == 2 {
Expand Down
2 changes: 1 addition & 1 deletion cli/internal/kubecmd/kubecmd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ func TestUpgradeNodeVersion(t *testing.T) {
outWriter: io.Discard,
}

err = upgrader.UpgradeNodeVersion(context.Background(), tc.conf, tc.force)
err = upgrader.UpgradeNodeVersion(context.Background(), tc.conf, tc.force, false, false)
// Check upgrades first because if we checked err first, UpgradeImage may error due to other reasons and still trigger an upgrade.
if tc.wantUpdate {
assert.NotNil(unstructuredClient.updatedObject)
Expand Down
4 changes: 2 additions & 2 deletions docs/docs/reference/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -475,8 +475,8 @@ constellation upgrade apply [flags]
--conformance enable conformance mode
-h, --help help for apply
--skip-helm-wait install helm charts without waiting for deployments to be ready
--skip-phases strings skip one or multiple phases of the upgrade process {infrastructure|helm|node|k8s}
--skip-phases strings comma-separated list of upgrade phases to skip
one or multiple of { infrastructure | helm | image | k8s }
-y, --yes run upgrades without further confirmation
WARNING: might delete your resources in case you are using cert-manager in your cluster. Please read the docs.
WARNING: might unintentionally overwrite measurements in the running cluster.
Expand Down

0 comments on commit c180014

Please sign in to comment.