From 4d56bbfd0b0d0d2439971adc45c85e79efc41aad Mon Sep 17 00:00:00 2001 From: Cavaughn Browne Date: Fri, 16 Feb 2024 18:31:37 +0000 Subject: [PATCH] use cluster.Spec without version bundles in upgrade management-components --- cmd/eksctl-anywhere/cmd/options.go | 122 +++++++++++++++++- .../cmd/upgrademanagementcomponents.go | 2 +- .../cmd/upgradeplanmanagementcomponents.go | 2 +- pkg/dependencies/factory.go | 6 +- pkg/eksd/upgrader.go | 6 - pkg/eksd/upgrader_test.go | 13 -- 6 files changed, 123 insertions(+), 28 deletions(-) diff --git a/cmd/eksctl-anywhere/cmd/options.go b/cmd/eksctl-anywhere/cmd/options.go index a2d060324c87..39feed0bd875 100644 --- a/cmd/eksctl-anywhere/cmd/options.go +++ b/cmd/eksctl-anywhere/cmd/options.go @@ -8,7 +8,9 @@ import ( "strings" "time" + "github.com/pkg/errors" "github.com/spf13/pflag" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" "github.com/aws/eks-anywhere/pkg/api/v1alpha1" @@ -19,11 +21,13 @@ import ( "github.com/aws/eks-anywhere/pkg/dependencies" "github.com/aws/eks-anywhere/pkg/files" "github.com/aws/eks-anywhere/pkg/kubeconfig" - "github.com/aws/eks-anywhere/pkg/logger" + "github.com/aws/eks-anywhere/pkg/manifests" + "github.com/aws/eks-anywhere/pkg/manifests/bundles" "github.com/aws/eks-anywhere/pkg/providers/cloudstack/decoder" "github.com/aws/eks-anywhere/pkg/types" "github.com/aws/eks-anywhere/pkg/validations" "github.com/aws/eks-anywhere/pkg/version" + releasev1 "github.com/aws/eks-anywhere/release/api/v1alpha1" ) const defaultTinkerbellNodeStartupTimeout = 20 * time.Minute @@ -156,10 +160,120 @@ func newClusterSpec(options clusterOptions) (*cluster.Spec, error) { return clusterSpec, nil } -func markFlagHidden(flagSet *pflag.FlagSet, flagName string) { - if err := flagSet.MarkHidden(flagName); err != nil { - logger.V(5).Info("Warning: Failed to mark flag as hidden: " + flagName) +func getBundles(cliVersion version.Info, bundlesManifestURL string) (*releasev1.Bundles, error) { + reader := files.NewReader(files.WithEKSAUserAgent("cli", cliVersion.GitVersion)) + manifestReader := manifests.NewReader(reader) + if bundlesManifestURL == "" { + return manifestReader.ReadBundlesForVersion(cliVersion.GitVersion) } + + return bundles.Read(reader, bundlesManifestURL) +} + +func getEksaRelease(cliVersion version.Info) (*releasev1.EksARelease, error) { + reader := files.NewReader(files.WithEKSAUserAgent("cli", cliVersion.GitVersion)) + manifestReader := manifests.NewReader(reader) + release, err := manifestReader.ReadReleaseForVersion(cliVersion.GitVersion) + if err != nil { + return nil, err + } + + return release, nil +} + +func getConfig(clusterConfigPath string, cliVersion version.Info) (*cluster.Config, error) { + reader := files.NewReader(files.WithEKSAUserAgent("cli", cliVersion.GitVersion)) + yaml, err := reader.ReadFile(clusterConfigPath) + if err != nil { + return nil, errors.Wrapf(err, "reading cluster config file") + } + + config, err := cluster.ParseConfig(yaml) + if err != nil { + return nil, errors.Wrapf(err, "parsing cluster config yaml") + } + + return config, nil +} + +// newBasicSpec creates a new cluster.Spec with the given Config, Bundles, and EKSARelease. +// This was created as a short term fix to management upgrades when the Cluster object is using an +// unsupported version of Kubernetes. +// +// When building the full cluster.Spec definition, we fetch the eksdReleases for +// the KubernetesVersions for all unique k8s versions specified in the Cluster for both CP and workers. +// If the Cluster object is using an unsupported version of Kubernetes, an error thrown +// because it does not exist in the Bundles file. This method allows to build a cluster.Spec without +// encountering this problem when performing only a management component upgrade. +func newBasicSpec(config *cluster.Config, bundles *releasev1.Bundles, eksaRelease *releasev1.EKSARelease) *cluster.Spec { + s := &cluster.Spec{} + s.Bundles = bundles + s.Config = config + + s.EKSARelease = eksaRelease + return s +} + +func readBasicClusterSpec(clusterConfigPath string, cliVersion version.Info, options clusterOptions) (*cluster.Spec, error) { + bundle, err := getBundles(cliVersion, options.bundlesOverride) + if err != nil { + return nil, err + } + bundle.Namespace = constants.EksaSystemNamespace + + config, err := getConfig(clusterConfigPath, cliVersion) + if err != nil { + return nil, err + } + + config.Cluster.Spec.BundlesRef = nil + + configManager, err := cluster.NewDefaultConfigManager() + if err != nil { + return nil, err + } + if err = configManager.SetDefaults(config); err != nil { + return nil, err + } + + release, err := getEksaRelease(cliVersion) + if err != nil { + return nil, err + } + + releaseVersion := v1alpha1.EksaVersion(release.Version) + config.Cluster.Spec.EksaVersion = &releaseVersion + eksaRelease := &releasev1.EKSARelease{ + TypeMeta: metav1.TypeMeta{ + Kind: releasev1.EKSAReleaseKind, + APIVersion: releasev1.SchemeBuilder.GroupVersion.String(), + }, + ObjectMeta: metav1.ObjectMeta{ + Name: releasev1.GenerateEKSAReleaseName(release.Version), + Namespace: constants.EksaSystemNamespace, + }, + Spec: releasev1.EKSAReleaseSpec{ + ReleaseDate: release.Date, + Version: release.Version, + GitCommit: release.GitCommit, + BundleManifestURL: release.BundleManifestUrl, + BundlesRef: releasev1.BundlesRef{ + APIVersion: releasev1.GroupVersion.String(), + Name: bundle.Name, + Namespace: bundle.Namespace, + }, + }, + } + + return newBasicSpec(config, bundle, eksaRelease), nil +} + +func newBasicClusterSpec(options clusterOptions) (*cluster.Spec, error) { + clusterSpec, err := readBasicClusterSpec(options.fileName, version.Get(), options) + if err != nil { + return nil, fmt.Errorf("unable to get cluster config from file: %v", err) + } + return clusterSpec, nil } func buildCliConfig(clusterSpec *cluster.Spec) *config.CliConfig { diff --git a/cmd/eksctl-anywhere/cmd/upgrademanagementcomponents.go b/cmd/eksctl-anywhere/cmd/upgrademanagementcomponents.go index 2bce8b7d9373..a3914fc5b100 100644 --- a/cmd/eksctl-anywhere/cmd/upgrademanagementcomponents.go +++ b/cmd/eksctl-anywhere/cmd/upgrademanagementcomponents.go @@ -34,7 +34,7 @@ var upgradeManagementComponentsCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) error { ctx := cmd.Context() - clusterSpec, err := newClusterSpec(umco.clusterOptions) + clusterSpec, err := newBasicClusterSpec(umco.clusterOptions) if err != nil { return err } diff --git a/cmd/eksctl-anywhere/cmd/upgradeplanmanagementcomponents.go b/cmd/eksctl-anywhere/cmd/upgradeplanmanagementcomponents.go index 743ee4d17110..04d26448c354 100644 --- a/cmd/eksctl-anywhere/cmd/upgradeplanmanagementcomponents.go +++ b/cmd/eksctl-anywhere/cmd/upgradeplanmanagementcomponents.go @@ -49,7 +49,7 @@ func (uc *upgradeClusterOptions) upgradePlanManagementComponents(ctx context.Con return fmt.Errorf("common validations failed due to: %v", err) } - newClusterSpec, err := newClusterSpec(uc.clusterOptions) + newClusterSpec, err := newBasicClusterSpec(uc.clusterOptions) if err != nil { return err } diff --git a/pkg/dependencies/factory.go b/pkg/dependencies/factory.go index 10bcca81609e..893e73665a39 100644 --- a/pkg/dependencies/factory.go +++ b/pkg/dependencies/factory.go @@ -139,14 +139,14 @@ func (d *Dependencies) Close(ctx context.Context) error { // ForSpec constructs a Factory using the bundle referenced by clusterSpec. func ForSpec(clusterSpec *cluster.Spec) *Factory { - versionsBundle := clusterSpec.RootVersionsBundle() - eksaToolsImage := versionsBundle.Eksa.CliTools + managementComponents := cluster.ManagementComponentsFromBundles(clusterSpec.Bundles) + eksaToolsImage := managementComponents.Eksa.CliTools return NewFactory(). UseExecutableImage(eksaToolsImage.VersionedImage()). WithRegistryMirror(registrymirror.FromCluster(clusterSpec.Cluster)). UseProxyConfiguration(clusterSpec.Cluster.ProxyConfiguration()). WithWriterFolder(clusterSpec.Cluster.Name). - WithDiagnosticCollectorImage(versionsBundle.Eksa.DiagnosticCollector.VersionedImage()) + WithDiagnosticCollectorImage(managementComponents.Eksa.DiagnosticCollector.VersionedImage()) } // Factory helps initialization. diff --git a/pkg/eksd/upgrader.go b/pkg/eksd/upgrader.go index 0645590b8499..f3e8fb9f1e7a 100644 --- a/pkg/eksd/upgrader.go +++ b/pkg/eksd/upgrader.go @@ -27,12 +27,6 @@ func NewUpgrader(client EksdInstallerClient, reader Reader, opts ...UpgraderOpt) // Upgrade checks for EKS-D updates, and if there are updates the EKS-D CRDs in the cluster. func (u *Upgrader) Upgrade(ctx context.Context, cluster *types.Cluster, currentSpec, newSpec *cluster.Spec) error { - logger.V(1).Info("Checking for EKS-D CRD updates") - changeDiff := ChangeDiff(currentSpec, newSpec) - if changeDiff == nil { - logger.V(1).Info("Nothing to update for EKS-D.") - return nil - } logger.V(1).Info("Updating EKS-D CRDs") if err := u.InstallEksdCRDs(ctx, newSpec, cluster); err != nil { return fmt.Errorf("updating EKS-D crds from bundles %d to bundles %d: %v", currentSpec.Bundles.Spec.Number, newSpec.Bundles.Spec.Number, err) diff --git a/pkg/eksd/upgrader_test.go b/pkg/eksd/upgrader_test.go index 6066bd9e0ab6..a655a964ada7 100644 --- a/pkg/eksd/upgrader_test.go +++ b/pkg/eksd/upgrader_test.go @@ -54,19 +54,6 @@ func newUpgraderTest(t *testing.T) *upgraderTest { } } -func TestEksdUpgradeNoSelfManaged(t *testing.T) { - tt := newUpgraderTest(t) - tt.newSpec.Cluster.SetManagedBy("management-cluster") - - tt.Expect(tt.eksdUpgrader.Upgrade(tt.ctx, tt.cluster, tt.currentSpec, tt.newSpec)).To(BeNil()) -} - -func TestEksdUpgradeNoChanges(t *testing.T) { - tt := newUpgraderTest(t) - - tt.Expect(tt.eksdUpgrader.Upgrade(tt.ctx, tt.cluster, tt.currentSpec, tt.newSpec)).To(BeNil()) -} - func TestEksdUpgradeSuccess(t *testing.T) { tt := newUpgraderTest(t)