From 14302905fdeaf9a7280dca56a4958e53b1dfbd8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Wei=C3=9Fe?= Date: Tue, 24 Oct 2023 09:29:41 +0200 Subject: [PATCH] Update flag help and add missing phases MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Weiße --- cli/internal/cmd/apply.go | 94 +++++++++++++++++++++++++------- cli/internal/cmd/upgradeapply.go | 36 ------------ 2 files changed, 74 insertions(+), 56 deletions(-) diff --git a/cli/internal/cmd/apply.go b/cli/internal/cmd/apply.go index 493019ddf9..9552143968 100644 --- a/cli/internal/cmd/apply.go +++ b/cli/internal/cmd/apply.go @@ -40,6 +40,57 @@ import ( k8serrors "k8s.io/apimachinery/pkg/api/errors" ) +const ( + // skipInfrastructurePhase skips the Terraform apply of the apply process. + skipInfrastructurePhase skipPhase = "infrastructure" + // skipInitPhase skips the init RPC of the apply process. + skipInitPhase skipPhase = "init" + // skipAttestationConfigPhase skips the attestation config upgrade of the apply process. + skipAttestationConfigPhase skipPhase = "attestationconfig" + // skipCertSANsPhase skips the cert SANs upgrade of the apply process. + skipCertSANsPhase skipPhase = "certsans" + // skipHelmPhase skips the helm upgrade of the apply process. + skipHelmPhase skipPhase = "helm" + // skipImagePhase skips the image upgrade of the apply process. + skipImagePhase skipPhase = "image" + // skipK8sPhase skips the Kubernetes version upgrade of the apply process. + skipK8sPhase skipPhase = "k8s" +) + +// skipPhase is a phase of the upgrade process that can be skipped. +type skipPhase string + +// skipPhases is a list of phases that can be skipped during the upgrade process. +type skipPhases map[skipPhase]struct{} + +// contains returns true if the list of phases contains the given phase. +func (s skipPhases) contains(phase skipPhase) bool { + _, ok := s[skipPhase(strings.ToLower(string(phase)))] + return ok +} + +// add a phase to the list of phases. +func (s *skipPhases) add(phases ...skipPhase) { + if *s == nil { + *s = make(skipPhases) + } + for _, phase := range phases { + (*s)[skipPhase(strings.ToLower(string(phase)))] = struct{}{} + } +} + +func printAllPhases() string { + return fmt.Sprintf("{ %s }", strings.Join([]string{ + string(skipInfrastructurePhase), + string(skipInitPhase), + string(skipAttestationConfigPhase), + string(skipCertSANsPhase), + string(skipHelmPhase), + string(skipImagePhase), + string(skipK8sPhase), + }, " | ")) +} + // NewApplyCmd creates the apply command. func NewApplyCmd() *cobra.Command { cmd := &cobra.Command{ @@ -53,13 +104,12 @@ func NewApplyCmd() *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().Bool("merge-kubeconfig", false, "merge Constellation kubeconfig file with default kubeconfig file in $HOME/.kube/config") - cmd.Flags().BoolP("yes", "y", false, "run upgrades without further confirmation\n"+ - "WARNING: might delete your resources in case you are using cert-manager in your cluster. Please read the docs.\n"+ - "WARNING: might unintentionally overwrite measurements in the running cluster.") + cmd.Flags().BoolP("yes", "y", false, "run command without further confirmation\n"+ + "WARNING: the command might delete or update existing resources without additional checks. Please read the docs.\n") cmd.Flags().Duration("timeout", 5*time.Minute, "change helm upgrade timeout\n"+ "Might be useful for slow connections or big clusters.") cmd.Flags().StringSlice("skip-phases", nil, "comma-separated list of upgrade phases to skip\n"+ - "one or multiple of { infrastructure | helm | image | k8s }") + fmt.Sprintf("one or multiple of %s", printAllPhases())) must(cmd.Flags().MarkHidden("timeout")) @@ -228,7 +278,7 @@ The control flow is as follows: │ │Not up to date │ │ │(Diff from Terraform plan)│ │ └────────────┐ │ - │ │ │Terraform + │ │ |Infrastructure │ ┌────────────▼──────────┐ │Phase │ │Apply Terraform updates│ │ │ └────────────┬──────────┘ │ @@ -254,14 +304,14 @@ The control flow is as follows: └──────────────┬───────────────┘ │ │ │ │ │ └───────────────┐ │ ───┘ - │ │ - ┌──────────▼──▼──────────┐ - │Apply Attestation Config│ - └─────────────┬──────────┘ - │ - ┌──────────────▼────────────┐ - │Extend API Server Cert SANs│ - └──────────────┬────────────┘ + │ │ ───┐ + ┌──────────▼──▼──────────┐ │AttestationConfig + │Apply Attestation Config│ │Phase + └─────────────┬──────────┘ ───┘ + │ ───┐ + ┌──────────────▼────────────┐ │CertSANs + │Extend API Server Cert SANs│ │Phase + └──────────────┬────────────┘ ───┘ │ ───┐ ┌──────────▼────────┐ │Helm │ Apply Helm Charts │ │Phase @@ -303,22 +353,26 @@ func (a *applyCmd) apply(cmd *cobra.Command, configFetcher attestationconfigapi. } // From now on we can assume a valid Kubernetes admin config file exists + a.log.Debugf("Creating Kubernetes client using %s", a.flags.pathPrefixer.PrefixPrintablePath(constants.AdminConfFilename)) kubeUpgrader, err := a.newKubeUpgrader(cmd.OutOrStdout(), constants.AdminConfFilename, a.log) if err != nil { return err } // Apply Attestation Config - a.log.Debugf("Creating Kubernetes client using %s", a.flags.pathPrefixer.PrefixPrintablePath(constants.AdminConfFilename)) - a.log.Debugf("Applying new attestation config to cluster") - if err := a.applyJoinConfig(cmd, kubeUpgrader, conf.GetAttestationConfig(), stateFile.ClusterValues.MeasurementSalt); err != nil { - return fmt.Errorf("applying attestation config: %w", err) + if !a.flags.skipPhases.contains(skipAttestationConfigPhase) { + a.log.Debugf("Applying new attestation config to cluster") + if err := a.applyJoinConfig(cmd, kubeUpgrader, conf.GetAttestationConfig(), stateFile.ClusterValues.MeasurementSalt); err != nil { + return fmt.Errorf("applying attestation config: %w", err) + } } // Extend API Server Cert SANs - sans := append([]string{stateFile.Infrastructure.ClusterEndpoint, conf.CustomEndpoint}, stateFile.Infrastructure.APIServerCertSANs...) - if err := kubeUpgrader.ExtendClusterConfigCertSANs(cmd.Context(), sans); err != nil { - return fmt.Errorf("extending cert SANs: %w", err) + if !a.flags.skipPhases.contains(skipCertSANsPhase) { + sans := append([]string{stateFile.Infrastructure.ClusterEndpoint, conf.CustomEndpoint}, stateFile.Infrastructure.APIServerCertSANs...) + if err := kubeUpgrader.ExtendClusterConfigCertSANs(cmd.Context(), sans); err != nil { + return fmt.Errorf("extending cert SANs: %w", err) + } } // Apply Helm Charts diff --git a/cli/internal/cmd/upgradeapply.go b/cli/internal/cmd/upgradeapply.go index d681f48541..8221e03691 100644 --- a/cli/internal/cmd/upgradeapply.go +++ b/cli/internal/cmd/upgradeapply.go @@ -10,7 +10,6 @@ import ( "context" "fmt" "io" - "strings" "time" "github.com/edgelesssys/constellation/v2/cli/internal/state" @@ -24,22 +23,6 @@ import ( apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" ) -const ( - // skipInitPhase skips the init RPC of the apply process. - skipInitPhase skipPhase = "init" - // skipInfrastructurePhase skips the terraform apply of the upgrade process. - skipInfrastructurePhase skipPhase = "infrastructure" - // skipHelmPhase skips the helm upgrade of the upgrade process. - skipHelmPhase skipPhase = "helm" - // skipImagePhase skips the image upgrade of the upgrade process. - skipImagePhase skipPhase = "image" - // skipK8sPhase skips the k8s upgrade of the upgrade process. - skipK8sPhase skipPhase = "k8s" -) - -// skipPhase is a phase of the upgrade process that can be skipped. -type skipPhase string - func newUpgradeApplyCmd() *cobra.Command { cmd := &cobra.Command{ Use: "apply", @@ -82,25 +65,6 @@ func diffAttestationCfg(currentAttestationCfg config.AttestationCfg, newAttestat return diff, nil } -// skipPhases is a list of phases that can be skipped during the upgrade process. -type skipPhases map[skipPhase]struct{} - -// contains returns true if the list of phases contains the given phase. -func (s skipPhases) contains(phase skipPhase) bool { - _, ok := s[skipPhase(strings.ToLower(string(phase)))] - return ok -} - -// add a phase to the list of phases. -func (s *skipPhases) add(phases ...skipPhase) { - if *s == nil { - *s = make(skipPhases) - } - for _, phase := range phases { - (*s)[skipPhase(strings.ToLower(string(phase)))] = struct{}{} - } -} - type kubernetesUpgrader interface { UpgradeNodeVersion(ctx context.Context, conf *config.Config, force, skipImage, skipK8s bool) error ExtendClusterConfigCertSANs(ctx context.Context, alternativeNames []string) error