diff --git a/Makefile b/Makefile index a02bec980b18..79d7c19620fb 100644 --- a/Makefile +++ b/Makefile @@ -568,7 +568,7 @@ mocks: ## Generate mocks ${MOCKGEN} -destination=pkg/bootstrapper/mocks/bootstrapper.go -package=mocks "github.com/aws/eks-anywhere/pkg/bootstrapper" ClusterClient ${MOCKGEN} -destination=pkg/git/providers/github/mocks/github.go -package=mocks "github.com/aws/eks-anywhere/pkg/git/providers/github" GithubClient ${MOCKGEN} -destination=pkg/git/mocks/git.go -package=mocks "github.com/aws/eks-anywhere/pkg/git" Client,ProviderClient - ${MOCKGEN} -destination=pkg/workflows/interfaces/mocks/clients.go -package=mocks "github.com/aws/eks-anywhere/pkg/workflows/interfaces" Bootstrapper,ClusterManager,GitOpsManager,Validator,CAPIManager,EksdInstaller,EksdUpgrader,PackageInstaller,ClusterUpgrader,ClusterCreator,ClientFactory,EksaInstaller,ClusterDeleter,ClusterMover + ${MOCKGEN} -destination=pkg/workflows/interfaces/mocks/clients.go -package=mocks "github.com/aws/eks-anywhere/pkg/workflows/interfaces" Bootstrapper,ClusterManager,GitOpsManager,Validator,CAPIManager,EksdInstaller,EksdUpgrader,PackageManager,ClusterUpgrader,ClusterCreator,ClientFactory,EksaInstaller,ClusterDeleter,ClusterMover ${MOCKGEN} -destination=pkg/git/gogithub/mocks/client.go -package=mocks "github.com/aws/eks-anywhere/pkg/git/gogithub" Client ${MOCKGEN} -destination=pkg/git/gitclient/mocks/client.go -package=mocks "github.com/aws/eks-anywhere/pkg/git/gitclient" GoGit ${MOCKGEN} -destination=pkg/validations/mocks/docker.go -package=mocks "github.com/aws/eks-anywhere/pkg/validations" DockerExecutable diff --git a/cmd/eksctl-anywhere/cmd/createcluster.go b/cmd/eksctl-anywhere/cmd/createcluster.go index 6452dafc6892..dc5b576d74b1 100644 --- a/cmd/eksctl-anywhere/cmd/createcluster.go +++ b/cmd/eksctl-anywhere/cmd/createcluster.go @@ -185,7 +185,7 @@ func (cc *createClusterOptions) createCluster(cmd *cobra.Command, _ []string) er WithGitOpsFlux(clusterSpec.Cluster, clusterSpec.FluxConfig, cliConfig). WithWriter(). WithEksdInstaller(). - WithPackageInstaller(clusterSpec, cc.installPackages, cc.managementKubeconfig). + WithPackageManager(clusterSpec, cc.installPackages, cc.managementKubeconfig). WithValidatorClients(). WithCreateClusterDefaulter(createCLIConfig). WithClusterApplier(). @@ -255,7 +255,7 @@ func (cc *createClusterOptions) createCluster(cmd *cobra.Command, _ []string) er deps.GitOpsFlux, deps.Writer, deps.EksdInstaller, - deps.PackageInstaller, + deps.PackageManager, deps.ClusterCreator, deps.UnAuthKubectlClient, ) @@ -272,7 +272,7 @@ func (cc *createClusterOptions) createCluster(cmd *cobra.Command, _ []string) er deps.GitOpsFlux, deps.Writer, deps.EksdInstaller, - deps.PackageInstaller, + deps.PackageManager, deps.ClusterCreator, deps.EksaInstaller, deps.ClusterMover, diff --git a/cmd/eksctl-anywhere/cmd/upgradecluster.go b/cmd/eksctl-anywhere/cmd/upgradecluster.go index cb199030269f..27866be23897 100644 --- a/cmd/eksctl-anywhere/cmd/upgradecluster.go +++ b/cmd/eksctl-anywhere/cmd/upgradecluster.go @@ -159,6 +159,7 @@ func (uc *upgradeClusterOptions) upgradeCluster(cmd *cobra.Command, args []strin WithEksdInstaller(). WithKubectl(). WithValidatorClients(). + WithPackageManagerWithoutWait(clusterSpec, "", uc.managementKubeconfig). WithUpgradeClusterDefaulter(upgradeCLIConfig) if uc.timeoutOptions.noTimeouts { @@ -212,6 +213,7 @@ func (uc *upgradeClusterOptions) upgradeCluster(cmd *cobra.Command, args []strin deps.EksdUpgrader, deps.EksdInstaller, deps.ClusterApplier, + deps.PackageManager, ) err = upgrade.Run(ctx, clusterSpec, managementCluster, upgradeValidations) @@ -225,7 +227,7 @@ func (uc *upgradeClusterOptions) upgradeCluster(cmd *cobra.Command, args []strin deps.Writer, deps.ClusterApplier, deps.EksdInstaller, - deps.PackageInstaller, + deps.PackageManager, ) err = upgradeWorkloadCluster.Run(ctx, workloadCluster, clusterSpec, upgradeValidations) } diff --git a/pkg/curatedpackages/packagecontrollerclient.go b/pkg/curatedpackages/packagecontrollerclient.go index 6d8e886ce7b6..493b6ed107eb 100644 --- a/pkg/curatedpackages/packagecontrollerclient.go +++ b/pkg/curatedpackages/packagecontrollerclient.go @@ -645,3 +645,10 @@ func WithRegistryAccessTester(registryTester RegistryAccessTester) func(client * config.registryAccessTester = registryTester } } + +// WithSkipWait sets skipWaitForPackageBundle. +func WithSkipWait() func(client *PackageControllerClient) { + return func(config *PackageControllerClient) { + config.skipWaitForPackageBundle = true + } +} diff --git a/pkg/curatedpackages/packagecontrollerclient_test.go b/pkg/curatedpackages/packagecontrollerclient_test.go index d31d3a4d6f35..dcdc9e44585d 100644 --- a/pkg/curatedpackages/packagecontrollerclient_test.go +++ b/pkg/curatedpackages/packagecontrollerclient_test.go @@ -524,6 +524,55 @@ func TestEnableWithEmptyProxy(t *testing.T) { } } +func TestEnableWithSkipWait(t *testing.T) { + for _, tt := range newPackageControllerTests(t) { + tt.command = curatedpackages.NewPackageControllerClient( + tt.chartManager, tt.kubectl, "billy", tt.kubeConfig, tt.chart, + tt.registryMirror, + curatedpackages.WithEksaSecretAccessKey(tt.eksaAccessKey), + curatedpackages.WithEksaRegion(tt.eksaRegion), + curatedpackages.WithEksaAccessKeyId(tt.eksaAccessID), + curatedpackages.WithSkipWait(), + curatedpackages.WithManagementClusterName(tt.clusterName), + curatedpackages.WithValuesFileWriter(tt.writer), + ) + clusterName := fmt.Sprintf("clusterName=%s", "billy") + valueFilePath := filepath.Join("billy", filewriter.DefaultTmpFolder, valueFileName) + ociURI := fmt.Sprintf("%s%s", "oci://", tt.registryMirror.ReplaceRegistry(tt.chart.Image())) + sourceRegistry, defaultRegistry, defaultImageRegistry := tt.command.GetCuratedPackagesRegistries(context.Background()) + sourceRegistry = fmt.Sprintf("sourceRegistry=%s", sourceRegistry) + defaultRegistry = fmt.Sprintf("defaultRegistry=%s", defaultRegistry) + defaultImageRegistry = fmt.Sprintf("defaultImageRegistry=%s", defaultImageRegistry) + if tt.registryMirror != nil { + t.Setenv("REGISTRY_USERNAME", "username") + t.Setenv("REGISTRY_PASSWORD", "password") + } else { + if tt.eksaRegion == "" { + tt.eksaRegion = "us-west-2" + } + defaultImageRegistry = strings.ReplaceAll(defaultImageRegistry, "us-west-2", tt.eksaRegion) + } + values := []string{sourceRegistry, defaultRegistry, defaultImageRegistry, clusterName} + if (tt.eksaAccessID == "" || tt.eksaAccessKey == "") && tt.registryMirror == nil { + values = append(values, "cronjob.suspend=true") + } + tt.chartManager.EXPECT().InstallChart(tt.ctx, tt.chart.Name, ociURI, tt.chart.Tag(), tt.kubeConfig, constants.EksaPackagesName, valueFilePath, false, values).Return(nil) + tt.kubectl.EXPECT(). + GetObject(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + DoAndReturn(getPBCSuccess(t)). + AnyTimes() + tt.kubectl.EXPECT(). + HasResource(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + DoAndReturn(func(_, _, _, _, _ interface{}) (bool, error) { return true, nil }). + AnyTimes() + + err := tt.command.Enable(tt.ctx) + if err != nil { + t.Errorf("Install Controller Should succeed when installation passes") + } + } +} + func TestEnableFail(t *testing.T) { for _, tt := range newPackageControllerTests(t) { clusterName := fmt.Sprintf("clusterName=%s", "billy") diff --git a/pkg/curatedpackages/packageinstaller.go b/pkg/curatedpackages/packageinstaller.go index ba473be21c43..02f93cd48571 100644 --- a/pkg/curatedpackages/packageinstaller.go +++ b/pkg/curatedpackages/packageinstaller.go @@ -67,6 +67,23 @@ func (pi *Installer) InstallCuratedPackages(ctx context.Context) { } } +// UpgradeCuratedPackages upgrades curated packages as part of the cluster upgrade. +func (pi *Installer) UpgradeCuratedPackages(ctx context.Context) { + if IsPackageControllerDisabled(pi.spec.Cluster) { + logger.Info("Package controller disabled") + return + } + PrintLicense() + if err := pi.installPackagesController(ctx); err != nil { + logger.MarkWarning("Failed to upgrade the optional EKS-A Curated Package Controller.", "warning", err) + return + } + + if err := pi.installPackages(ctx); err != nil { + logger.MarkWarning("Failed upgrading curated packages on the cluster.", "error", err) + } +} + func (pi *Installer) installPackagesController(ctx context.Context) error { logger.Info("Enabling curated packages on the cluster") err := pi.packageController.Enable(ctx) diff --git a/pkg/dependencies/factory.go b/pkg/dependencies/factory.go index 312090557e99..60f855589f86 100644 --- a/pkg/dependencies/factory.go +++ b/pkg/dependencies/factory.go @@ -94,7 +94,7 @@ type Dependencies struct { closers []types.Closer CliConfig *cliconfig.CliConfig CreateCliConfig *cliconfig.CreateClusterCLIConfig - PackageInstaller interfaces.PackageInstaller + PackageManager interfaces.PackageManager BundleRegistry curatedpackages.BundleRegistry PackageControllerClient *curatedpackages.PackageControllerClient PackageClient curatedpackages.PackageHandler @@ -1322,16 +1322,17 @@ func (f *Factory) WithGitOpsFlux(clusterConfig *v1alpha1.Cluster, fluxConfig *v1 return f } -func (f *Factory) WithPackageInstaller(spec *cluster.Spec, packagesLocation, kubeConfig string) *Factory { +// WithPackageManager builds a package manager. +func (f *Factory) WithPackageManager(spec *cluster.Spec, packagesLocation, kubeConfig string) *Factory { f.WithKubectl().WithPackageControllerClient(spec, kubeConfig).WithPackageClient() - f.buildSteps = append(f.buildSteps, func(ctx context.Context) error { - if f.dependencies.PackageInstaller != nil { + f.buildSteps = append(f.buildSteps, func(_ context.Context) error { + if f.dependencies.PackageManager != nil { return nil } managementClusterName := getManagementClusterName(spec) mgmtKubeConfig := kubeconfig.ResolveFilename(kubeConfig, managementClusterName) - f.dependencies.PackageInstaller = curatedpackages.NewInstaller( + f.dependencies.PackageManager = curatedpackages.NewInstaller( f.dependencies.Kubectl, f.dependencies.PackageClient, f.dependencies.PackageControllerClient, @@ -1344,10 +1345,18 @@ func (f *Factory) WithPackageInstaller(spec *cluster.Spec, packagesLocation, kub return f } -func (f *Factory) WithPackageControllerClient(spec *cluster.Spec, kubeConfig string) *Factory { +// WithPackageManagerWithoutWait builds a package manager that doesn't wait for active bundles. +func (f *Factory) WithPackageManagerWithoutWait(spec *cluster.Spec, packagesLocation, kubeConfig string) *Factory { + f.WithPackageControllerClient(spec, kubeConfig, curatedpackages.WithSkipWait()). + WithPackageManager(spec, packagesLocation, kubeConfig) + return f +} + +// WithPackageControllerClient builds a client for package controller. +func (f *Factory) WithPackageControllerClient(spec *cluster.Spec, kubeConfig string, opts ...curatedpackages.PackageControllerClientOpt) *Factory { f.WithHelm(helm.WithInsecure()).WithKubectl() - f.buildSteps = append(f.buildSteps, func(ctx context.Context) error { + f.buildSteps = append(f.buildSteps, func(_ context.Context) error { if f.dependencies.PackageControllerClient != nil || spec == nil { return nil } @@ -1374,13 +1383,8 @@ func (f *Factory) WithPackageControllerClient(spec *cluster.Spec, kubeConfig str if bundle == nil { return fmt.Errorf("could not find VersionsBundle") } - f.dependencies.PackageControllerClient = curatedpackages.NewPackageControllerClient( - f.dependencies.Helm, - f.dependencies.Kubectl, - spec.Cluster.Name, - mgmtKubeConfig, - &bundle.PackageController.HelmChart, - f.registryMirror, + + options := []curatedpackages.PackageControllerClientOpt{ curatedpackages.WithEksaAccessKeyId(eksaAccessKeyID), curatedpackages.WithEksaSecretAccessKey(eksaSecretKey), curatedpackages.WithEksaRegion(eksaRegion), @@ -1391,6 +1395,18 @@ func (f *Factory) WithPackageControllerClient(spec *cluster.Spec, kubeConfig str curatedpackages.WithManagementClusterName(managementClusterName), curatedpackages.WithValuesFileWriter(writer), curatedpackages.WithClusterSpec(spec), + } + + options = append(options, opts...) + + f.dependencies.PackageControllerClient = curatedpackages.NewPackageControllerClient( + f.dependencies.Helm, + f.dependencies.Kubectl, + spec.Cluster.Name, + mgmtKubeConfig, + &bundle.PackageController.HelmChart, + f.registryMirror, + options..., ) return nil }) diff --git a/pkg/dependencies/factory_test.go b/pkg/dependencies/factory_test.go index d8d0e1c9bb81..7e43b4246630 100644 --- a/pkg/dependencies/factory_test.go +++ b/pkg/dependencies/factory_test.go @@ -433,10 +433,46 @@ func TestFactoryBuildWithPackageInstaller(t *testing.T) { WithLocalExecutables(). WithHelm(helm.WithInsecure()). WithKubectl(). - WithPackageInstaller(spec, "/test/packages.yaml", "kubeconfig.kubeconfig"). + WithPackageManager(spec, "/test/packages.yaml", "kubeconfig.kubeconfig"). Build(context.Background()) tt.Expect(err).To(BeNil()) - tt.Expect(deps.PackageInstaller).NotTo(BeNil()) + tt.Expect(deps.PackageManager).NotTo(BeNil()) +} + +func TestFactoryBuildWithPackageInstallerWithoutWait(t *testing.T) { + spec := &cluster.Spec{ + Config: &cluster.Config{ + Cluster: &anywherev1.Cluster{ + ObjectMeta: v1.ObjectMeta{ + Name: "test-cluster", + }, + Spec: anywherev1.ClusterSpec{ + KubernetesVersion: "1.19", + }, + }, + }, + VersionsBundles: map[anywherev1.KubernetesVersion]*cluster.VersionsBundle{ + "1.19": { + VersionsBundle: &v1alpha1.VersionsBundle{ + PackageController: v1alpha1.PackageBundle{ + HelmChart: v1alpha1.Image{ + URI: "test_registry/test/eks-anywhere-packages:v1", + Name: "test_chart", + }, + }, + }, + }, + }, + } + tt := newTest(t, vsphere) + deps, err := dependencies.NewFactory(). + WithLocalExecutables(). + WithHelm(helm.WithInsecure()). + WithKubectl(). + WithPackageManagerWithoutWait(spec, "/test/packages.yaml", "kubeconfig.kubeconfig"). + Build(context.Background()) + tt.Expect(err).To(BeNil()) + tt.Expect(deps.PackageManager).NotTo(BeNil()) } func TestFactoryBuildWithCuratedPackagesCustomRegistry(t *testing.T) { diff --git a/pkg/task/task.go b/pkg/task/task.go index 24ac57991786..118e6176f910 100644 --- a/pkg/task/task.go +++ b/pkg/task/task.go @@ -36,7 +36,7 @@ type CommandContext struct { Writer filewriter.FileWriter EksdInstaller interfaces.EksdInstaller EksaInstaller interfaces.EksaInstaller - PackageInstaller interfaces.PackageInstaller + PackageManager interfaces.PackageManager EksdUpgrader interfaces.EksdUpgrader ClusterUpgrader interfaces.ClusterUpgrader ClusterCreator interfaces.ClusterCreator diff --git a/pkg/workflows/interfaces/interfaces.go b/pkg/workflows/interfaces/interfaces.go index 37b2d0e01c9a..182765cc4720 100644 --- a/pkg/workflows/interfaces/interfaces.go +++ b/pkg/workflows/interfaces/interfaces.go @@ -76,8 +76,10 @@ type EksdUpgrader interface { Upgrade(ctx context.Context, cluster *types.Cluster, currentSpec, newSpec *cluster.Spec) error } -type PackageInstaller interface { +// PackageManager handles installation and upgrades of curated packages. +type PackageManager interface { InstallCuratedPackages(ctx context.Context) + UpgradeCuratedPackages(ctx context.Context) } // ClusterUpgrader upgrades the cluster and waits until it's ready. diff --git a/pkg/workflows/interfaces/mocks/clients.go b/pkg/workflows/interfaces/mocks/clients.go index 1e534ea03926..bdb7d47c53cf 100644 --- a/pkg/workflows/interfaces/mocks/clients.go +++ b/pkg/workflows/interfaces/mocks/clients.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/aws/eks-anywhere/pkg/workflows/interfaces (interfaces: Bootstrapper,ClusterManager,GitOpsManager,Validator,CAPIManager,EksdInstaller,EksdUpgrader,PackageInstaller,ClusterUpgrader,ClusterCreator,ClientFactory,EksaInstaller,ClusterDeleter,ClusterMover) +// Source: github.com/aws/eks-anywhere/pkg/workflows/interfaces (interfaces: Bootstrapper,ClusterManager,GitOpsManager,Validator,CAPIManager,EksdInstaller,EksdUpgrader,PackageManager,ClusterUpgrader,ClusterCreator,ClientFactory,EksaInstaller,ClusterDeleter,ClusterMover) // Package mocks is a generated GoMock package. package mocks @@ -685,39 +685,51 @@ func (mr *MockEksdUpgraderMockRecorder) Upgrade(arg0, arg1, arg2, arg3 interface return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Upgrade", reflect.TypeOf((*MockEksdUpgrader)(nil).Upgrade), arg0, arg1, arg2, arg3) } -// MockPackageInstaller is a mock of PackageInstaller interface. -type MockPackageInstaller struct { +// MockPackageManager is a mock of PackageManager interface. +type MockPackageManager struct { ctrl *gomock.Controller - recorder *MockPackageInstallerMockRecorder + recorder *MockPackageManagerMockRecorder } -// MockPackageInstallerMockRecorder is the mock recorder for MockPackageInstaller. -type MockPackageInstallerMockRecorder struct { - mock *MockPackageInstaller +// MockPackageManagerMockRecorder is the mock recorder for MockPackageManager. +type MockPackageManagerMockRecorder struct { + mock *MockPackageManager } -// NewMockPackageInstaller creates a new mock instance. -func NewMockPackageInstaller(ctrl *gomock.Controller) *MockPackageInstaller { - mock := &MockPackageInstaller{ctrl: ctrl} - mock.recorder = &MockPackageInstallerMockRecorder{mock} +// NewMockPackageManager creates a new mock instance. +func NewMockPackageManager(ctrl *gomock.Controller) *MockPackageManager { + mock := &MockPackageManager{ctrl: ctrl} + mock.recorder = &MockPackageManagerMockRecorder{mock} return mock } // EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockPackageInstaller) EXPECT() *MockPackageInstallerMockRecorder { +func (m *MockPackageManager) EXPECT() *MockPackageManagerMockRecorder { return m.recorder } // InstallCuratedPackages mocks base method. -func (m *MockPackageInstaller) InstallCuratedPackages(arg0 context.Context) { +func (m *MockPackageManager) InstallCuratedPackages(arg0 context.Context) { m.ctrl.T.Helper() m.ctrl.Call(m, "InstallCuratedPackages", arg0) } // InstallCuratedPackages indicates an expected call of InstallCuratedPackages. -func (mr *MockPackageInstallerMockRecorder) InstallCuratedPackages(arg0 interface{}) *gomock.Call { +func (mr *MockPackageManagerMockRecorder) InstallCuratedPackages(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InstallCuratedPackages", reflect.TypeOf((*MockPackageInstaller)(nil).InstallCuratedPackages), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InstallCuratedPackages", reflect.TypeOf((*MockPackageManager)(nil).InstallCuratedPackages), arg0) +} + +// UpgradeCuratedPackages mocks base method. +func (m *MockPackageManager) UpgradeCuratedPackages(arg0 context.Context) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "UpgradeCuratedPackages", arg0) +} + +// UpgradeCuratedPackages indicates an expected call of UpgradeCuratedPackages. +func (mr *MockPackageManagerMockRecorder) UpgradeCuratedPackages(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpgradeCuratedPackages", reflect.TypeOf((*MockPackageManager)(nil).UpgradeCuratedPackages), arg0) } // MockClusterUpgrader is a mock of ClusterUpgrader interface. diff --git a/pkg/workflows/management/create.go b/pkg/workflows/management/create.go index 23b1425d9f81..8679d9a8c351 100644 --- a/pkg/workflows/management/create.go +++ b/pkg/workflows/management/create.go @@ -12,17 +12,17 @@ import ( // Create is a schema for create cluster. type Create struct { - bootstrapper interfaces.Bootstrapper - clientFactory interfaces.ClientFactory - provider providers.Provider - clusterManager interfaces.ClusterManager - gitOpsManager interfaces.GitOpsManager - writer filewriter.FileWriter - eksdInstaller interfaces.EksdInstaller - packageInstaller interfaces.PackageInstaller - clusterCreator interfaces.ClusterCreator - eksaInstaller interfaces.EksaInstaller - clusterMover interfaces.ClusterMover + bootstrapper interfaces.Bootstrapper + clientFactory interfaces.ClientFactory + provider providers.Provider + clusterManager interfaces.ClusterManager + gitOpsManager interfaces.GitOpsManager + writer filewriter.FileWriter + eksdInstaller interfaces.EksdInstaller + packageManager interfaces.PackageManager + clusterCreator interfaces.ClusterCreator + eksaInstaller interfaces.EksaInstaller + clusterMover interfaces.ClusterMover } // NewCreate builds a new create construct. @@ -30,42 +30,42 @@ func NewCreate(bootstrapper interfaces.Bootstrapper, clientFactory interfaces.ClientFactory, provider providers.Provider, clusterManager interfaces.ClusterManager, gitOpsManager interfaces.GitOpsManager, writer filewriter.FileWriter, eksdInstaller interfaces.EksdInstaller, - packageInstaller interfaces.PackageInstaller, + packageManager interfaces.PackageManager, clusterCreator interfaces.ClusterCreator, eksaInstaller interfaces.EksaInstaller, mover interfaces.ClusterMover, ) *Create { return &Create{ - bootstrapper: bootstrapper, - clientFactory: clientFactory, - provider: provider, - clusterManager: clusterManager, - gitOpsManager: gitOpsManager, - writer: writer, - eksdInstaller: eksdInstaller, - packageInstaller: packageInstaller, - clusterCreator: clusterCreator, - eksaInstaller: eksaInstaller, - clusterMover: mover, + bootstrapper: bootstrapper, + clientFactory: clientFactory, + provider: provider, + clusterManager: clusterManager, + gitOpsManager: gitOpsManager, + writer: writer, + eksdInstaller: eksdInstaller, + packageManager: packageManager, + clusterCreator: clusterCreator, + eksaInstaller: eksaInstaller, + clusterMover: mover, } } // Run runs all the create management cluster tasks. func (c *Create) Run(ctx context.Context, clusterSpec *cluster.Spec, validator interfaces.Validator) error { commandContext := &task.CommandContext{ - Bootstrapper: c.bootstrapper, - ClientFactory: c.clientFactory, - Provider: c.provider, - ClusterManager: c.clusterManager, - GitOpsManager: c.gitOpsManager, - ClusterSpec: clusterSpec, - Writer: c.writer, - Validations: validator, - EksdInstaller: c.eksdInstaller, - PackageInstaller: c.packageInstaller, - ClusterCreator: c.clusterCreator, - EksaInstaller: c.eksaInstaller, - ClusterMover: c.clusterMover, + Bootstrapper: c.bootstrapper, + ClientFactory: c.clientFactory, + Provider: c.provider, + ClusterManager: c.clusterManager, + GitOpsManager: c.gitOpsManager, + ClusterSpec: clusterSpec, + Writer: c.writer, + Validations: validator, + EksdInstaller: c.eksdInstaller, + PackageManager: c.packageManager, + ClusterCreator: c.clusterCreator, + EksaInstaller: c.eksaInstaller, + ClusterMover: c.clusterMover, } return task.NewTaskRunner(&setupAndValidateCreate{}, c.writer).RunTask(ctx, commandContext) diff --git a/pkg/workflows/management/create_curated_packages.go b/pkg/workflows/management/create_curated_packages.go index a3c9d407a23b..14ab0465f202 100644 --- a/pkg/workflows/management/create_curated_packages.go +++ b/pkg/workflows/management/create_curated_packages.go @@ -9,7 +9,7 @@ import ( type installCuratedPackagesTask struct{} func (s *installCuratedPackagesTask) Run(ctx context.Context, commandContext *task.CommandContext) task.Task { - commandContext.PackageInstaller.InstallCuratedPackages(ctx) + commandContext.PackageManager.InstallCuratedPackages(ctx) return nil } diff --git a/pkg/workflows/management/create_test.go b/pkg/workflows/management/create_test.go index 3ec27e74b5a4..010319aaacb3 100644 --- a/pkg/workflows/management/create_test.go +++ b/pkg/workflows/management/create_test.go @@ -27,7 +27,7 @@ import ( type createTestSetup struct { t *testing.T - packageInstaller *mocks.MockPackageInstaller + packageInstaller *mocks.MockPackageManager clusterManager *mocks.MockClusterManager bootstrapper *mocks.MockBootstrapper gitOpsManager *mocks.MockGitOpsManager @@ -62,7 +62,7 @@ func newCreateTest(t *testing.T) *createTestSetup { eksdInstaller := mocks.NewMockEksdInstaller(mockCtrl) eksaInstaller := mocks.NewMockEksaInstaller(mockCtrl) - packageInstaller := mocks.NewMockPackageInstaller(mockCtrl) + packageInstaller := mocks.NewMockPackageManager(mockCtrl) datacenterConfig := &v1alpha1.VSphereDatacenterConfig{} machineConfigs := []providers.MachineConfig{&v1alpha1.VSphereMachineConfig{}} diff --git a/pkg/workflows/management/post_cluster_upgrade.go b/pkg/workflows/management/post_cluster_upgrade.go index 78c7975fa446..ca3f8f6ab128 100644 --- a/pkg/workflows/management/post_cluster_upgrade.go +++ b/pkg/workflows/management/post_cluster_upgrade.go @@ -28,7 +28,7 @@ func (s *postClusterUpgrade) Run(ctx context.Context, commandContext *task.Comma logger.Info(fmt.Sprintf("management cluster CAPI backup file not found: %v", err)) } - return nil + return &upgradeCuratedPackagesTask{} } func (s *postClusterUpgrade) Name() string { diff --git a/pkg/workflows/management/upgrade.go b/pkg/workflows/management/upgrade.go index e8de7b767fa2..001336c0feb6 100644 --- a/pkg/workflows/management/upgrade.go +++ b/pkg/workflows/management/upgrade.go @@ -24,6 +24,7 @@ type Upgrade struct { eksdUpgrader interfaces.EksdUpgrader upgradeChangeDiff *types.ChangeDiff clusterUpgrader interfaces.ClusterUpgrader + packageManager interfaces.PackageManager } // NewUpgrade builds a new upgrade construct. @@ -35,6 +36,7 @@ func NewUpgrade(clientFactory interfaces.ClientFactory, provider providers.Provi eksdUpgrader interfaces.EksdUpgrader, eksdInstaller interfaces.EksdInstaller, clusterUpgrade interfaces.ClusterUpgrader, + packageManager interfaces.PackageManager, ) *Upgrade { upgradeChangeDiff := types.NewChangeDiff() return &Upgrade{ @@ -48,6 +50,7 @@ func NewUpgrade(clientFactory interfaces.ClientFactory, provider providers.Provi eksdInstaller: eksdInstaller, upgradeChangeDiff: upgradeChangeDiff, clusterUpgrader: clusterUpgrade, + packageManager: packageManager, } } @@ -67,6 +70,7 @@ func (c *Upgrade) Run(ctx context.Context, clusterSpec *cluster.Spec, management EksdUpgrader: c.eksdUpgrader, UpgradeChangeDiff: c.upgradeChangeDiff, ClusterUpgrader: c.clusterUpgrader, + PackageManager: c.packageManager, } if features.IsActive(features.CheckpointEnabled()) { return task.NewTaskRunner(&setupAndValidateUpgrade{}, c.writer, task.WithCheckpointFile()).RunTask(ctx, commandContext) diff --git a/pkg/workflows/management/upgrade_curated_packages.go b/pkg/workflows/management/upgrade_curated_packages.go new file mode 100644 index 000000000000..13a8c7978142 --- /dev/null +++ b/pkg/workflows/management/upgrade_curated_packages.go @@ -0,0 +1,31 @@ +package management + +import ( + "context" + + "github.com/aws/eks-anywhere/pkg/task" +) + +type upgradeCuratedPackagesTask struct{} + +func (s *upgradeCuratedPackagesTask) Run(ctx context.Context, commandContext *task.CommandContext) task.Task { + if commandContext.CurrentClusterSpec.Cluster.Spec.RegistryMirrorConfiguration.Equal(commandContext.ClusterSpec.Cluster.Spec.RegistryMirrorConfiguration) { + return nil + } + + commandContext.PackageManager.UpgradeCuratedPackages(ctx) + + return nil +} + +func (s *upgradeCuratedPackagesTask) Name() string { + return "upgrade-curated-packages" +} + +func (s *upgradeCuratedPackagesTask) Restore(_ context.Context, _ *task.CommandContext, _ *task.CompletedTask) (task.Task, error) { + return nil, nil +} + +func (s *upgradeCuratedPackagesTask) Checkpoint() *task.CompletedTask { + return nil +} diff --git a/pkg/workflows/management/upgrade_test.go b/pkg/workflows/management/upgrade_test.go index df6a979eff02..dc42c4a9a324 100644 --- a/pkg/workflows/management/upgrade_test.go +++ b/pkg/workflows/management/upgrade_test.go @@ -10,12 +10,14 @@ import ( "github.com/golang/mock/gomock" . "github.com/onsi/gomega" + appsv1 "k8s.io/api/apps/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/aws/eks-anywhere/internal/test" "github.com/aws/eks-anywhere/pkg/api/v1alpha1" "github.com/aws/eks-anywhere/pkg/clients/kubernetes" "github.com/aws/eks-anywhere/pkg/cluster" + "github.com/aws/eks-anywhere/pkg/constants" "github.com/aws/eks-anywhere/pkg/features" writermocks "github.com/aws/eks-anywhere/pkg/filewriter/mocks" "github.com/aws/eks-anywhere/pkg/providers" @@ -48,6 +50,7 @@ type upgradeManagementTestSetup struct { managementCluster *types.Cluster managementStatePath string management *management.Upgrade + packages *mocks.MockPackageManager } func newUpgradeManagementTest(t *testing.T) *upgradeManagementTestSetup { @@ -65,6 +68,7 @@ func newUpgradeManagementTest(t *testing.T) *upgradeManagementTestSetup { capiUpgrader := mocks.NewMockCAPIManager(mockCtrl) machineConfigs := []providers.MachineConfig{&v1alpha1.VSphereMachineConfig{}} clusterUpgrader := mocks.NewMockClusterUpgrader(mockCtrl) + packageUpgrader := mocks.NewMockPackageManager(mockCtrl) management := management.NewUpgrade( clientFactory, provider, @@ -75,6 +79,7 @@ func newUpgradeManagementTest(t *testing.T) *upgradeManagementTestSetup { eksdUpgrader, eksdInstaller, clusterUpgrader, + packageUpgrader, ) for _, e := range featureEnvVars { @@ -111,6 +116,7 @@ func newUpgradeManagementTest(t *testing.T) *upgradeManagementTestSetup { datacenterConfig: datacenterConfig, machineConfigs: machineConfigs, management: management, + packages: packageUpgrader, ctx: context.Background(), currentManagementComponents: cluster.ManagementComponentsFromBundles(currentClusterSpec.Bundles), newManagementComponents: cluster.ManagementComponentsFromBundles(newClusterSpec.Bundles), @@ -308,6 +314,10 @@ func (c *upgradeManagementTestSetup) expectPreflightValidationsToPass() { c.validator.EXPECT().PreflightValidations(c.ctx).Return(nil) } +func (c *upgradeManagementTestSetup) expectPackagesUpgrade() { + c.packages.EXPECT().UpgradeCuratedPackages(c.ctx) +} + func TestUpgradeManagementRunUpdateSetupFailed(t *testing.T) { os.Unsetenv(features.CheckpointEnabledEnvVar) features.ClearCache() @@ -730,6 +740,45 @@ func TestUpgradeManagementRunResumeClusterResourcesReconcileFailed(t *testing.T) } } +func TestUpgradeManagementRunUpgradeCuratedPackagesSuccess(t *testing.T) { + os.Unsetenv(features.CheckpointEnabledEnvVar) + features.ClearCache() + tt := newUpgradeManagementClusterTest(t) + tt.newClusterSpec.Cluster.Spec.RegistryMirrorConfiguration = &v1alpha1.RegistryMirrorConfiguration{} + packagesManager := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "eks-anywhere-packages", + Namespace: constants.EksaPackagesName, + }, + } + tt.client = test.NewFakeKubeClient(tt.currentClusterSpec.Cluster, tt.currentClusterSpec.EKSARelease, tt.currentClusterSpec.Bundles, packagesManager) + tt.expectSetup() + tt.expectPreflightValidationsToPass() + tt.expectUpdateSecrets(nil) + tt.expectEnsureManagementEtcdCAPIComponentsExist(nil) + tt.expectUpgradeCoreComponents() + tt.expectPauseGitOpsReconcile(nil) + tt.expectBackupManagementFromCluster(nil) + tt.expectPauseCAPIWorkloadClusters(nil) + tt.expectDatacenterConfig() + tt.expectMachineConfigs() + tt.expectInstallEksdManifest(nil) + tt.expectApplyBundles(nil) + tt.expectApplyReleases(nil) + tt.expectUpgradeManagementCluster() + tt.expectResumeCAPIWorkloadClustersAPI(nil) + tt.expectUpdateGitEksaSpec(nil) + tt.expectForceReconcileGitRepo(nil) + tt.expectResumeGitOpsReconcile(nil) + tt.expectWriteManagementClusterConfig(nil) + tt.expectPackagesUpgrade() + + err := tt.run() + if err != nil { + t.Fatalf("UpgradeManagement.Run() err = %v, want err = nil", err) + } +} + func TestUpgradeManagementRunSuccess(t *testing.T) { os.Unsetenv(features.CheckpointEnabledEnvVar) features.ClearCache() diff --git a/pkg/workflows/workload/create.go b/pkg/workflows/workload/create.go index 219a173a3d12..e7aa5146b746 100644 --- a/pkg/workflows/workload/create.go +++ b/pkg/workflows/workload/create.go @@ -19,7 +19,7 @@ type Create struct { writer filewriter.FileWriter eksdInstaller interfaces.EksdInstaller clusterCreator interfaces.ClusterCreator - packageInstaller interfaces.PackageInstaller + packageInstaller interfaces.PackageManager } // NewCreate builds a new create construct. @@ -27,7 +27,7 @@ func NewCreate(provider providers.Provider, clusterManager interfaces.ClusterManager, gitOpsManager interfaces.GitOpsManager, writer filewriter.FileWriter, eksdInstaller interfaces.EksdInstaller, - packageInstaller interfaces.PackageInstaller, + packageInstaller interfaces.PackageManager, clusterCreator interfaces.ClusterCreator, clientFactory interfaces.ClientFactory, ) *Create { diff --git a/pkg/workflows/workload/create_test.go b/pkg/workflows/workload/create_test.go index d5f667f3a8a1..5005ca2b5d32 100644 --- a/pkg/workflows/workload/create_test.go +++ b/pkg/workflows/workload/create_test.go @@ -35,7 +35,7 @@ type createTestSetup struct { writer *writermocks.MockFileWriter validator *mocks.MockValidator eksd *mocks.MockEksdInstaller - packageInstaller *mocks.MockPackageInstaller + packageInstaller *mocks.MockPackageManager clusterCreator *mocks.MockClusterCreator datacenterConfig providers.DatacenterConfig machineConfigs []providers.MachineConfig @@ -56,7 +56,7 @@ func newCreateTest(t *testing.T) *createTestSetup { provider := providermocks.NewMockProvider(mockCtrl) writer := writermocks.NewMockFileWriter(mockCtrl) eksd := mocks.NewMockEksdInstaller(mockCtrl) - packageInstaller := mocks.NewMockPackageInstaller(mockCtrl) + packageInstaller := mocks.NewMockPackageManager(mockCtrl) eksdInstaller := mocks.NewMockEksdInstaller(mockCtrl) datacenterConfig := &v1alpha1.VSphereDatacenterConfig{} diff --git a/pkg/workflows/workload/upgrade.go b/pkg/workflows/workload/upgrade.go index 722e4f52fef1..db955c59b99c 100644 --- a/pkg/workflows/workload/upgrade.go +++ b/pkg/workflows/workload/upgrade.go @@ -20,7 +20,7 @@ type Upgrade struct { writer filewriter.FileWriter eksdInstaller interfaces.EksdInstaller clusterUpgrader interfaces.ClusterUpgrader - packageInstaller interfaces.PackageInstaller + packageInstaller interfaces.PackageManager } // NewUpgrade builds a new upgrade construct. @@ -30,7 +30,7 @@ func NewUpgrade(clientFactory interfaces.ClientFactory, writer filewriter.FileWriter, clusterUpgrader interfaces.ClusterUpgrader, eksdInstaller interfaces.EksdInstaller, - packageInstaller interfaces.PackageInstaller, + packageInstaller interfaces.PackageManager, ) *Upgrade { return &Upgrade{ clientFactory: clientFactory, diff --git a/pkg/workflows/workload/upgrade_test.go b/pkg/workflows/workload/upgrade_test.go index 1f9e3e8f3cb3..05fb1e2ad2cd 100644 --- a/pkg/workflows/workload/upgrade_test.go +++ b/pkg/workflows/workload/upgrade_test.go @@ -34,7 +34,7 @@ type upgradeTestSetup struct { writer *writermocks.MockFileWriter validator *mocks.MockValidator eksd *mocks.MockEksdInstaller - packageInstaller *mocks.MockPackageInstaller + packageInstaller *mocks.MockPackageManager clusterUpgrader *mocks.MockClusterUpgrader datacenterConfig providers.DatacenterConfig machineConfigs []providers.MachineConfig @@ -55,7 +55,7 @@ func newUpgradeTest(t *testing.T) *upgradeTestSetup { provider := providermocks.NewMockProvider(mockCtrl) writer := writermocks.NewMockFileWriter(mockCtrl) eksd := mocks.NewMockEksdInstaller(mockCtrl) - packageInstaller := mocks.NewMockPackageInstaller(mockCtrl) + packageInstaller := mocks.NewMockPackageManager(mockCtrl) eksdInstaller := mocks.NewMockEksdInstaller(mockCtrl) datacenterConfig := &v1alpha1.VSphereDatacenterConfig{}