From 7f339080170e3e64433bcb933cb36ee2fb99f268 Mon Sep 17 00:00:00 2001 From: Cavaughn Browne Date: Fri, 12 Jan 2024 18:19:55 +0000 Subject: [PATCH] add eksa management version annotation to management cluster --- cmd/eksctl-anywhere/cmd/createcluster.go | 9 ++- cmd/eksctl-anywhere/cmd/upgradecluster.go | 5 ++ .../cmd/upgrademanagementcomponents.go | 8 ++- internal/test/cluster.go | 8 ++- pkg/api/v1alpha1/cluster_types.go | 16 +++++ pkg/api/v1alpha1/cluster_types_test.go | 34 ++++++++++ pkg/task/task.go | 2 + pkg/workflows/create.go | 22 ++++++- pkg/workflows/create_test.go | 64 ++++++++++++++++++- pkg/workflows/management/core_components.go | 14 ++++ pkg/workflows/management/upgrade.go | 6 +- .../upgrade_management_components.go | 5 ++ .../upgrade_management_components_test.go | 12 ++++ pkg/workflows/management/upgrade_test.go | 48 ++++++++++++++ 14 files changed, 246 insertions(+), 7 deletions(-) diff --git a/cmd/eksctl-anywhere/cmd/createcluster.go b/cmd/eksctl-anywhere/cmd/createcluster.go index 5f8735e8944c5..b9bd6afeaffa8 100644 --- a/cmd/eksctl-anywhere/cmd/createcluster.go +++ b/cmd/eksctl-anywhere/cmd/createcluster.go @@ -205,7 +205,14 @@ func (cc *createClusterOptions) createCluster(cmd *cobra.Command, _ []string) er return err } + clusterKubeconfig := kubeconfig.FromClusterName(clusterSpec.Cluster.Name) + client, err := deps.UnAuthKubeClient.BuildClientFromKubeconfig(clusterKubeconfig) + if err != nil { + return err + } + createCluster := workflows.NewCreate( + client, deps.Bootstrapper, deps.Provider, deps.ClusterManager, @@ -222,7 +229,7 @@ func (cc *createClusterOptions) createCluster(cmd *cobra.Command, _ []string) er Spec: clusterSpec, WorkloadCluster: &types.Cluster{ Name: clusterSpec.Cluster.Name, - KubeconfigFile: kubeconfig.FromClusterName(clusterSpec.Cluster.Name), + KubeconfigFile: clusterKubeconfig, }, ManagementCluster: mgmt, Provider: deps.Provider, diff --git a/cmd/eksctl-anywhere/cmd/upgradecluster.go b/cmd/eksctl-anywhere/cmd/upgradecluster.go index 34ce201beeaa4..cfb4280db629c 100644 --- a/cmd/eksctl-anywhere/cmd/upgradecluster.go +++ b/cmd/eksctl-anywhere/cmd/upgradecluster.go @@ -201,8 +201,13 @@ func (uc *upgradeClusterOptions) upgradeCluster(cmd *cobra.Command, args []strin upgradeValidations := upgradevalidations.New(validationOpts) + client, err := deps.UnAuthKubeClient.BuildClientFromKubeconfig(workloadCluster.KubeconfigFile) + if err != nil { + return err + } if clusterConfig.IsSelfManaged() { upgrade := management.NewUpgrade( + client, deps.Provider, deps.CAPIManager, deps.ClusterManager, diff --git a/cmd/eksctl-anywhere/cmd/upgrademanagementcomponents.go b/cmd/eksctl-anywhere/cmd/upgrademanagementcomponents.go index f12ac3622e0ea..e2ff7dc221987 100644 --- a/cmd/eksctl-anywhere/cmd/upgrademanagementcomponents.go +++ b/cmd/eksctl-anywhere/cmd/upgrademanagementcomponents.go @@ -70,7 +70,13 @@ var upgradeManagementComponentsCmd = &cobra.Command{ } defer close(cmd.Context(), deps) + clusterKubeconfig := kubeconfig.FromClusterName(clusterSpec.Cluster.Name) + client, err := deps.UnAuthKubeClient.BuildClientFromKubeconfig(clusterKubeconfig) + if err != nil { + return err + } runner := management.NewUpgradeManagementComponentsRunner( + client, deps.Provider, deps.CAPIManager, deps.ClusterManager, @@ -82,7 +88,7 @@ var upgradeManagementComponentsCmd = &cobra.Command{ managementCluster := &types.Cluster{ Name: clusterSpec.Cluster.Name, - KubeconfigFile: kubeconfig.FromClusterName(clusterSpec.Cluster.Name), + KubeconfigFile: clusterKubeconfig, } validator := management.NewUMCValidator(managementCluster, deps.Kubectl) diff --git a/internal/test/cluster.go b/internal/test/cluster.go index a930f513497ba..7d8babe4a6d1e 100644 --- a/internal/test/cluster.go +++ b/internal/test/cluster.go @@ -47,8 +47,12 @@ func NewClusterSpec(opts ...ClusterSpecOpt) *cluster.Spec { } s.VersionsBundles = map[v1alpha1.KubernetesVersion]*cluster.VersionsBundle{ v1alpha1.Kube119: { - VersionsBundle: &releasev1alpha1.VersionsBundle{}, - KubeDistro: &cluster.KubeDistro{}, + VersionsBundle: &releasev1alpha1.VersionsBundle{ + Eksa: releasev1alpha1.EksaBundle{ + Version: "v0.0.0-dev+build.0000+000000", + }, + }, + KubeDistro: &cluster.KubeDistro{}, }, } s.Bundles = &releasev1alpha1.Bundles{} diff --git a/pkg/api/v1alpha1/cluster_types.go b/pkg/api/v1alpha1/cluster_types.go index fa0b107b42d88..f40da3f43fa9d 100644 --- a/pkg/api/v1alpha1/cluster_types.go +++ b/pkg/api/v1alpha1/cluster_types.go @@ -41,6 +41,11 @@ const ( // cluster object. managementAnnotation = "anywhere.eks.amazonaws.com/managed-by" + // managementComponentsVersionAnnotation is an annotation applied to an EKS-A management cluster pointing to the current version of the management components. + // The value for this annotation is expected to correspond to an EKSARelease object version, following semantic version convention: e.g. v0.18.3 + // This is an internal EKS-A managed annotation, not meant to be updated manually. + managementComponentsVersionAnnotation = "anywhere.eks.amazonaws.com/eksa-management-components-version" + // defaultEksaNamespace is the default namespace for EKS-A resources when not specified. defaultEksaNamespace = "default" @@ -1294,6 +1299,17 @@ func (c *Cluster) ControlPlaneAnnotation() string { return controlPlaneAnnotation } +// SetManagmentComponentsVersion sets the `eksa-management-components version` annotation on the Cluster object. +func (c *Cluster) SetManagmentComponentsVersion(version string) { + if c.IsManaged() { + return + } + if c.Annotations == nil { + c.Annotations = make(map[string]string, 1) + } + c.Annotations[managementComponentsVersionAnnotation] = version +} + // DisableControlPlaneIPCheck sets the `skip-ip-check` annotation on the Cluster object. func (c *Cluster) DisableControlPlaneIPCheck() { if c.Annotations == nil { diff --git a/pkg/api/v1alpha1/cluster_types_test.go b/pkg/api/v1alpha1/cluster_types_test.go index cd8687ea6a341..86787528abfb4 100644 --- a/pkg/api/v1alpha1/cluster_types_test.go +++ b/pkg/api/v1alpha1/cluster_types_test.go @@ -3230,3 +3230,37 @@ func TestValidateCluster(t *testing.T) { }) } } + +func TestCluster_SetManagmentComponentsVersion(t *testing.T) { + managmentClusterName := "mgmt-cluster" + expectedManagmentComponentVersion := "v0.0.0-dev+build.0000" + + testCases := []struct { + name string + cluster *v1alpha1.Cluster + wantAnnotations map[string]string + }{ + { + name: "self-managed cluster", + cluster: baseCluster(func(c *v1alpha1.Cluster) { + c.SetManagmentComponentsVersion(expectedManagmentComponentVersion) + }), + wantAnnotations: map[string]string{"anywhere.eks.amazonaws.com/eksa-management-components-version": expectedManagmentComponentVersion}, + }, + { + name: "managed cluster", + cluster: baseCluster(func(c *v1alpha1.Cluster) { + c.SetManagedBy(managmentClusterName) + c.SetManagmentComponentsVersion(expectedManagmentComponentVersion) + }), + wantAnnotations: map[string]string{"anywhere.eks.amazonaws.com/managed-by": managmentClusterName}, + }, + } + + for _, tt := range testCases { + t.Run(tt.name, func(t *testing.T) { + g := NewWithT(t) + g.Expect(tt.cluster.Annotations).To(Equal(tt.wantAnnotations)) + }) + } +} diff --git a/pkg/task/task.go b/pkg/task/task.go index de2d5da191e7d..1805608441fa5 100644 --- a/pkg/task/task.go +++ b/pkg/task/task.go @@ -9,6 +9,7 @@ import ( "sigs.k8s.io/yaml" + "github.com/aws/eks-anywhere/pkg/clients/kubernetes" "github.com/aws/eks-anywhere/pkg/cluster" "github.com/aws/eks-anywhere/pkg/filewriter" "github.com/aws/eks-anywhere/pkg/logger" @@ -27,6 +28,7 @@ type Task interface { // Command context maintains the mutable and shared entities. type CommandContext struct { + Client kubernetes.Client Bootstrapper interfaces.Bootstrapper Provider providers.Provider ClusterManager interfaces.ClusterManager diff --git a/pkg/workflows/create.go b/pkg/workflows/create.go index 7843417a1e78e..54f993663a42a 100644 --- a/pkg/workflows/create.go +++ b/pkg/workflows/create.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + "github.com/aws/eks-anywhere/pkg/clients/kubernetes" "github.com/aws/eks-anywhere/pkg/cluster" "github.com/aws/eks-anywhere/pkg/clustermarshaller" "github.com/aws/eks-anywhere/pkg/constants" @@ -16,7 +17,12 @@ import ( "github.com/aws/eks-anywhere/pkg/workflows/interfaces" ) +const ( + eksaFieldManager = "eks-a-cli" +) + type Create struct { + client kubernetes.Client bootstrapper interfaces.Bootstrapper provider providers.Provider clusterManager interfaces.ClusterManager @@ -26,12 +32,14 @@ type Create struct { packageInstaller interfaces.PackageInstaller } -func NewCreate(bootstrapper interfaces.Bootstrapper, provider providers.Provider, +// NewCreate returns a Create instance. +func NewCreate(client kubernetes.Client, bootstrapper interfaces.Bootstrapper, provider providers.Provider, clusterManager interfaces.ClusterManager, gitOpsManager interfaces.GitOpsManager, writer filewriter.FileWriter, eksdInstaller interfaces.EksdInstaller, packageInstaller interfaces.PackageInstaller, ) *Create { return &Create{ + client: client, bootstrapper: bootstrapper, provider: provider, clusterManager: clusterManager, @@ -51,6 +59,7 @@ func (c *Create) Run(ctx context.Context, clusterSpec *cluster.Spec, validator i } } commandContext := &task.CommandContext{ + Client: c.client, Bootstrapper: c.bootstrapper, Provider: c.provider, ClusterManager: c.clusterManager, @@ -372,6 +381,17 @@ func (s *InstallEksaComponentsTask) Run(ctx context.Context, commandContext *tas commandContext.SetError(err) return &CollectDiagnosticsTask{} } + + commandContext.ClusterSpec.Cluster.SetManagmentComponentsVersion(commandContext.ClusterSpec.EKSARelease.Spec.Version) + if err := commandContext.Client.ApplyServerSide(ctx, + eksaFieldManager, + commandContext.ClusterSpec.Cluster, + kubernetes.ApplyServerSideOptions{ForceOwnership: true}, + ); err != nil { + commandContext.SetError(err) + return &CollectDiagnosticsTask{} + } + err = commandContext.ClusterManager.ResumeEKSAControllerReconcile(ctx, targetCluster, commandContext.ClusterSpec, commandContext.Provider) if err != nil { commandContext.SetError(err) diff --git a/pkg/workflows/create_test.go b/pkg/workflows/create_test.go index 2a2975c1978b0..bc48aa1019ebc 100644 --- a/pkg/workflows/create_test.go +++ b/pkg/workflows/create_test.go @@ -11,6 +11,8 @@ import ( "github.com/aws/eks-anywhere/internal/test" "github.com/aws/eks-anywhere/pkg/api/v1alpha1" "github.com/aws/eks-anywhere/pkg/bootstrapper" + "github.com/aws/eks-anywhere/pkg/clients/kubernetes" + clientmocks "github.com/aws/eks-anywhere/pkg/clients/kubernetes/mocks" "github.com/aws/eks-anywhere/pkg/cluster" writermocks "github.com/aws/eks-anywhere/pkg/filewriter/mocks" "github.com/aws/eks-anywhere/pkg/providers" @@ -23,6 +25,7 @@ import ( type createTestSetup struct { t *testing.T + client *clientmocks.MockClient packageInstaller *mocks.MockPackageInstaller bootstrapper *mocks.MockBootstrapper clusterManager *mocks.MockClusterManager @@ -43,6 +46,7 @@ type createTestSetup struct { func newCreateTest(t *testing.T) *createTestSetup { mockCtrl := gomock.NewController(t) + client := clientmocks.NewMockClient(mockCtrl) bootstrapper := mocks.NewMockBootstrapper(mockCtrl) clusterManager := mocks.NewMockClusterManager(mockCtrl) gitOpsManager := mocks.NewMockGitOpsManager(mockCtrl) @@ -53,11 +57,12 @@ func newCreateTest(t *testing.T) *createTestSetup { datacenterConfig := &v1alpha1.VSphereDatacenterConfig{} machineConfigs := []providers.MachineConfig{&v1alpha1.VSphereMachineConfig{}} - workflow := workflows.NewCreate(bootstrapper, provider, clusterManager, gitOpsManager, writer, eksd, packageInstaller) + workflow := workflows.NewCreate(client, bootstrapper, provider, clusterManager, gitOpsManager, writer, eksd, packageInstaller) validator := mocks.NewMockValidator(mockCtrl) return &createTestSetup{ t: t, + client: client, bootstrapper: bootstrapper, clusterManager: clusterManager, gitOpsManager: gitOpsManager, @@ -202,6 +207,13 @@ func (c *createTestSetup) expectInstallEksaComponents() { c.eksd.EXPECT().InstallEksdManifest( c.ctx, c.clusterSpec, c.workloadCluster), + c.client.EXPECT().ApplyServerSide( + c.ctx, + "eks-a-cli", + c.clusterSpec.Cluster, + kubernetes.ApplyServerSideOptions{ForceOwnership: true}, + ), + c.clusterManager.EXPECT().ResumeEKSAControllerReconcile(c.ctx, c.workloadCluster, c.clusterSpec, c.provider), ) } @@ -224,6 +236,13 @@ func (c *createTestSetup) skipInstallEksaComponents() { c.eksd.EXPECT().InstallEksdManifest( c.ctx, c.clusterSpec, c.bootstrapCluster), + c.client.EXPECT().ApplyServerSide( + c.ctx, + "eks-a-cli", + c.clusterSpec.Cluster, + kubernetes.ApplyServerSideOptions{ForceOwnership: true}, + ), + c.clusterManager.EXPECT().ResumeEKSAControllerReconcile(c.ctx, c.bootstrapCluster, c.clusterSpec, c.provider), ) } @@ -293,6 +312,49 @@ func TestCreateRunSuccess(t *testing.T) { } } +func TestCreateRunInstallEksaComponentsApplyFail(t *testing.T) { + wantError := errors.New("test error") + test := newCreateTest(t) + + test.expectSetup() + test.expectPreflightValidationsToPass() + test.expectCreateBootstrap() + test.expectCreateWorkload() + test.expectInstallResourcesOnManagementTask() + test.expectMoveManagement() + gomock.InOrder( + test.clusterManager.EXPECT().InstallCustomComponents( + test.ctx, test.clusterSpec, test.workloadCluster, test.provider), + + test.eksd.EXPECT().InstallEksdCRDs(test.ctx, test.clusterSpec, test.workloadCluster), + + test.provider.EXPECT().DatacenterConfig(test.clusterSpec).Return(test.datacenterConfig), + + test.provider.EXPECT().MachineConfigs(test.clusterSpec).Return(test.machineConfigs), + + test.clusterManager.EXPECT().CreateEKSAResources( + test.ctx, test.workloadCluster, test.clusterSpec, test.datacenterConfig, test.machineConfigs, + ), + + test.eksd.EXPECT().InstallEksdManifest( + test.ctx, test.clusterSpec, test.workloadCluster), + + test.client.EXPECT().ApplyServerSide( + test.ctx, + "eks-a-cli", + test.clusterSpec.Cluster, + kubernetes.ApplyServerSideOptions{ForceOwnership: true}, + ).Return(wantError), + ) + test.clusterManager.EXPECT().SaveLogsManagementCluster(test.ctx, test.clusterSpec, test.bootstrapCluster) + test.clusterManager.EXPECT().SaveLogsWorkloadCluster(test.ctx, test.provider, test.clusterSpec, test.workloadCluster) + test.writer.EXPECT().Write(fmt.Sprintf("%s-checkpoint.yaml", test.clusterSpec.Cluster.Name), gomock.Any()) + + if err := test.run(); err == nil { + t.Fatalf("Create.Run() err = %v, want err = %v", err, wantError) + } +} + func TestCreateRunAWSIamConfigFail(t *testing.T) { wantError := errors.New("test error") test := newCreateTest(t) diff --git a/pkg/workflows/management/core_components.go b/pkg/workflows/management/core_components.go index e4a933a146cc5..2c973cf889a1b 100644 --- a/pkg/workflows/management/core_components.go +++ b/pkg/workflows/management/core_components.go @@ -3,12 +3,17 @@ package management import ( "context" + "github.com/aws/eks-anywhere/pkg/clients/kubernetes" "github.com/aws/eks-anywhere/pkg/logger" "github.com/aws/eks-anywhere/pkg/task" "github.com/aws/eks-anywhere/pkg/types" "github.com/aws/eks-anywhere/pkg/workflows" ) +const ( + eksaFieldManager = "eks-a-cli" +) + type ensureEtcdCAPIComponentsExist struct{} // Run ensureEtcdCAPIComponentsExist ensures ETCD CAPI providers on the management cluster. @@ -85,6 +90,15 @@ func runUpgradeCoreComponents(ctx context.Context, commandContext *task.CommandC } commandContext.UpgradeChangeDiff.Append(changeDiff) + commandContext.ClusterSpec.Cluster.SetManagmentComponentsVersion(commandContext.ClusterSpec.EKSARelease.Spec.Version) + if err := commandContext.Client.ApplyServerSide(ctx, + eksaFieldManager, + commandContext.ClusterSpec.Cluster, + kubernetes.ApplyServerSideOptions{ForceOwnership: true}, + ); err != nil { + commandContext.SetError(err) + return err + } return nil } diff --git a/pkg/workflows/management/upgrade.go b/pkg/workflows/management/upgrade.go index be9bc38a940de..ff40730328b16 100644 --- a/pkg/workflows/management/upgrade.go +++ b/pkg/workflows/management/upgrade.go @@ -3,6 +3,7 @@ package management import ( "context" + "github.com/aws/eks-anywhere/pkg/clients/kubernetes" "github.com/aws/eks-anywhere/pkg/cluster" "github.com/aws/eks-anywhere/pkg/features" "github.com/aws/eks-anywhere/pkg/filewriter" @@ -14,6 +15,7 @@ import ( // Upgrade is a schema for upgrade cluster. type Upgrade struct { + client kubernetes.Client provider providers.Provider clusterManager interfaces.ClusterManager gitOpsManager interfaces.GitOpsManager @@ -26,7 +28,7 @@ type Upgrade struct { } // NewUpgrade builds a new upgrade construct. -func NewUpgrade(provider providers.Provider, +func NewUpgrade(client kubernetes.Client, provider providers.Provider, capiManager interfaces.CAPIManager, clusterManager interfaces.ClusterManager, gitOpsManager interfaces.GitOpsManager, @@ -37,6 +39,7 @@ func NewUpgrade(provider providers.Provider, ) *Upgrade { upgradeChangeDiff := types.NewChangeDiff() return &Upgrade{ + client: client, provider: provider, clusterManager: clusterManager, gitOpsManager: gitOpsManager, @@ -52,6 +55,7 @@ func NewUpgrade(provider providers.Provider, // Run Upgrade implements upgrade functionality for management cluster's upgrade operation. func (c *Upgrade) Run(ctx context.Context, clusterSpec *cluster.Spec, managementCluster *types.Cluster, validator interfaces.Validator) error { commandContext := &task.CommandContext{ + Client: c.client, Provider: c.provider, ClusterManager: c.clusterManager, GitOpsManager: c.gitOpsManager, diff --git a/pkg/workflows/management/upgrade_management_components.go b/pkg/workflows/management/upgrade_management_components.go index 083e3f2d0eda4..b0637e178eb78 100644 --- a/pkg/workflows/management/upgrade_management_components.go +++ b/pkg/workflows/management/upgrade_management_components.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + "github.com/aws/eks-anywhere/pkg/clients/kubernetes" "github.com/aws/eks-anywhere/pkg/cluster" "github.com/aws/eks-anywhere/pkg/executables" "github.com/aws/eks-anywhere/pkg/filewriter" @@ -18,6 +19,7 @@ import ( // UpgradeManagementComponentsWorkflow is a schema for upgrade management components. type UpgradeManagementComponentsWorkflow struct { + client kubernetes.Client provider providers.Provider clusterManager interfaces.ClusterManager gitOpsManager interfaces.GitOpsManager @@ -29,6 +31,7 @@ type UpgradeManagementComponentsWorkflow struct { // NewUpgradeManagementComponentsRunner builds a new UpgradeManagementCommponents construct. func NewUpgradeManagementComponentsRunner( + client kubernetes.Client, provider providers.Provider, capiManager interfaces.CAPIManager, clusterManager interfaces.ClusterManager, @@ -38,6 +41,7 @@ func NewUpgradeManagementComponentsRunner( eksdInstaller interfaces.EksdInstaller, ) *UpgradeManagementComponentsWorkflow { return &UpgradeManagementComponentsWorkflow{ + client: client, provider: provider, clusterManager: clusterManager, gitOpsManager: gitOpsManager, @@ -87,6 +91,7 @@ func (u *UMCValidator) PreflightValidations(ctx context.Context) []validations.V // Run Upgrade implements upgrade functionality for management cluster's upgrade operation. func (umc *UpgradeManagementComponentsWorkflow) Run(ctx context.Context, clusterSpec *cluster.Spec, managementCluster *types.Cluster, validator interfaces.Validator) error { commandContext := &task.CommandContext{ + Client: umc.client, Provider: umc.provider, ClusterManager: umc.clusterManager, ManagementCluster: managementCluster, diff --git a/pkg/workflows/management/upgrade_management_components_test.go b/pkg/workflows/management/upgrade_management_components_test.go index 09c07265c7c2f..78b27ec8562de 100644 --- a/pkg/workflows/management/upgrade_management_components_test.go +++ b/pkg/workflows/management/upgrade_management_components_test.go @@ -9,6 +9,8 @@ import ( "github.com/golang/mock/gomock" "github.com/aws/eks-anywhere/internal/test" + "github.com/aws/eks-anywhere/pkg/clients/kubernetes" + clientmocks "github.com/aws/eks-anywhere/pkg/clients/kubernetes/mocks" writermocks "github.com/aws/eks-anywhere/pkg/filewriter/mocks" "github.com/aws/eks-anywhere/pkg/kubeconfig" providermocks "github.com/aws/eks-anywhere/pkg/providers/mocks" @@ -43,6 +45,7 @@ var eksdChangeDiff = types.NewChangeDiff(&types.ComponentChangeDiff{ type TestMocks struct { mockCtrl *gomock.Controller + client *clientmocks.MockClient clusterManager *mocks.MockClusterManager gitOpsManager *mocks.MockGitOpsManager provider *providermocks.MockProvider @@ -57,6 +60,7 @@ func NewTestMocks(t *testing.T) *TestMocks { mockCtrl := gomock.NewController(t) return &TestMocks{ mockCtrl: mockCtrl, + client: clientmocks.NewMockClient(mockCtrl), clusterManager: mocks.NewMockClusterManager(mockCtrl), gitOpsManager: mocks.NewMockGitOpsManager(mockCtrl), provider: providermocks.NewMockProvider(mockCtrl), @@ -71,6 +75,7 @@ func NewTestMocks(t *testing.T) *TestMocks { func TestRunnerHappyPath(t *testing.T) { mocks := NewTestMocks(t) runner := NewUpgradeManagementComponentsRunner( + mocks.client, mocks.provider, mocks.capiManager, mocks.clusterManager, @@ -101,6 +106,12 @@ func TestRunnerHappyPath(t *testing.T) { mocks.gitOpsManager.EXPECT().Upgrade(ctx, managementCluster, curSpec, newSpec).Return(fluxChangeDiff, nil), mocks.clusterManager.EXPECT().Upgrade(ctx, managementCluster, curSpec, newSpec).Return(eksaChangeDiff, nil), mocks.eksdUpgrader.EXPECT().Upgrade(ctx, managementCluster, curSpec, newSpec).Return(eksdChangeDiff, nil), + mocks.client.EXPECT().ApplyServerSide( + ctx, + "eks-a-cli", + newSpec.Cluster, + kubernetes.ApplyServerSideOptions{ForceOwnership: true}, + ).Return(nil), mocks.clusterManager.EXPECT().ApplyBundles( ctx, newSpec, managementCluster, ).Return(nil), @@ -121,6 +132,7 @@ func TestRunnerHappyPath(t *testing.T) { func TestRunnerStopsWhenValidationFailed(t *testing.T) { mocks := NewTestMocks(t) runner := NewUpgradeManagementComponentsRunner( + mocks.client, mocks.provider, mocks.capiManager, mocks.clusterManager, diff --git a/pkg/workflows/management/upgrade_test.go b/pkg/workflows/management/upgrade_test.go index 367c2409e0b88..aa1cefb2788d3 100644 --- a/pkg/workflows/management/upgrade_test.go +++ b/pkg/workflows/management/upgrade_test.go @@ -12,6 +12,8 @@ import ( "github.com/aws/eks-anywhere/internal/test" "github.com/aws/eks-anywhere/pkg/api/v1alpha1" + "github.com/aws/eks-anywhere/pkg/clients/kubernetes" + clientmocks "github.com/aws/eks-anywhere/pkg/clients/kubernetes/mocks" "github.com/aws/eks-anywhere/pkg/cluster" "github.com/aws/eks-anywhere/pkg/features" writermocks "github.com/aws/eks-anywhere/pkg/filewriter/mocks" @@ -24,6 +26,7 @@ import ( type upgradeManagementTestSetup struct { t *testing.T + client *clientmocks.MockClient clusterManager *mocks.MockClusterManager gitOpsManager *mocks.MockGitOpsManager provider *providermocks.MockProvider @@ -46,6 +49,7 @@ type upgradeManagementTestSetup struct { func newUpgradeManagementTest(t *testing.T) *upgradeManagementTestSetup { featureEnvVars := []string{} mockCtrl := gomock.NewController(t) + client := clientmocks.NewMockClient(mockCtrl) clusterManager := mocks.NewMockClusterManager(mockCtrl) gitOpsManager := mocks.NewMockGitOpsManager(mockCtrl) provider := providermocks.NewMockProvider(mockCtrl) @@ -58,6 +62,7 @@ func newUpgradeManagementTest(t *testing.T) *upgradeManagementTestSetup { machineConfigs := []providers.MachineConfig{&v1alpha1.VSphereMachineConfig{}} clusterUpgrader := mocks.NewMockClusterUpgrader(mockCtrl) management := management.NewUpgrade( + client, provider, capiUpgrader, clusterManager, @@ -74,6 +79,7 @@ func newUpgradeManagementTest(t *testing.T) *upgradeManagementTestSetup { return &upgradeManagementTestSetup{ t: t, + client: client, clusterManager: clusterManager, gitOpsManager: gitOpsManager, provider: provider, @@ -163,6 +169,15 @@ func (c *upgradeManagementTestSetup) expectUpgradeCoreComponents() { ) } +func (c *upgradeManagementTestSetup) expectApplyServerSide(err error) { + c.client.EXPECT().ApplyServerSide( + c.ctx, + "eks-a-cli", + c.newClusterSpec.Cluster, + kubernetes.ApplyServerSideOptions{ForceOwnership: true}, + ).Return(err) +} + func (c *upgradeManagementTestSetup) expectBackupManagementFromCluster(err error) { gomock.InOrder( c.clusterManager.EXPECT().BackupCAPI(c.ctx, c.managementCluster, c.managementStatePath, "").Return(err), @@ -349,6 +364,7 @@ func TestUpgradeManagementRunFailedBackup(t *testing.T) { test.expectEnsureManagementEtcdCAPIComponentsExist(nil) test.expectPauseGitOpsReconcile(nil) test.expectUpgradeCoreComponents() + test.expectApplyServerSide(nil) test.expectBackupManagementFromCluster(errors.New("")) test.expectBackupManagementInfrastructureFromCluster(errors.New("")) test.expectSaveLogs() @@ -370,6 +386,7 @@ func TestUpgradeManagementRunPauseWorkloadCAPIFailed(t *testing.T) { test.expectEnsureManagementEtcdCAPIComponentsExist(nil) test.expectPauseGitOpsReconcile(nil) test.expectUpgradeCoreComponents() + test.expectApplyServerSide(nil) test.expectBackupManagementFromCluster(nil) test.expectPauseCAPIWorkloadClusters(errors.New("")) test.expectSaveLogs() @@ -381,6 +398,28 @@ func TestUpgradeManagementRunPauseWorkloadCAPIFailed(t *testing.T) { } } +func TestUpgradeManagementRunFailedUpgradeApplyServerSide(t *testing.T) { + os.Unsetenv(features.CheckpointEnabledEnvVar) + features.ClearCache() + test := newUpgradeManagementClusterTest(t) + test.expectSetup() + test.expectPreflightValidationsToPass() + test.expectUpdateSecrets(nil) + test.expectEnsureManagementEtcdCAPIComponentsExist(nil) + test.expectPauseGitOpsReconcile(nil) + test.expectUpgradeCoreComponents() + test.expectApplyServerSide(errors.New("")) + test.expectDatacenterConfig() + test.expectMachineConfigs() + test.expectSaveLogs() + test.expectWriteCheckpointFile() + + err := test.run() + if err == nil { + t.Fatal("UpgradeManagement.Run() err = nil, want err not nil") + } +} + func TestUpgradeManagementRunFailedUpgradeInstallEksd(t *testing.T) { os.Unsetenv(features.CheckpointEnabledEnvVar) features.ClearCache() @@ -391,6 +430,7 @@ func TestUpgradeManagementRunFailedUpgradeInstallEksd(t *testing.T) { test.expectEnsureManagementEtcdCAPIComponentsExist(nil) test.expectPauseGitOpsReconcile(nil) test.expectUpgradeCoreComponents() + test.expectApplyServerSide(nil) test.expectBackupManagementFromCluster(nil) test.expectPauseCAPIWorkloadClusters(nil) test.expectDatacenterConfig() @@ -417,6 +457,7 @@ func TestUpgradeManagementRunFailedUpgradeApplyBundles(t *testing.T) { test.expectEnsureManagementEtcdCAPIComponentsExist(nil) test.expectPauseGitOpsReconcile(nil) test.expectUpgradeCoreComponents() + test.expectApplyServerSide(nil) test.expectBackupManagementFromCluster(nil) test.expectPauseCAPIWorkloadClusters(nil) test.expectDatacenterConfig() @@ -441,6 +482,7 @@ func TestUpgradeManagementRunFailedUpgradeApplyReleases(t *testing.T) { test.expectEnsureManagementEtcdCAPIComponentsExist(nil) test.expectPauseGitOpsReconcile(nil) test.expectUpgradeCoreComponents() + test.expectApplyServerSide(nil) test.expectBackupManagementFromCluster(nil) test.expectPauseCAPIWorkloadClusters(nil) test.expectDatacenterConfig() @@ -466,6 +508,7 @@ func TestUpgradeManagementRunFailedUpgrade(t *testing.T) { test.expectEnsureManagementEtcdCAPIComponentsExist(nil) test.expectPauseGitOpsReconcile(nil) test.expectUpgradeCoreComponents() + test.expectApplyServerSide(nil) test.expectBackupManagementFromCluster(nil) test.expectPauseCAPIWorkloadClusters(nil) test.expectDatacenterConfig() @@ -492,6 +535,7 @@ func TestUpgradeManagementRunResumeCAPIWorkloadFailed(t *testing.T) { test.expectUpdateSecrets(nil) test.expectEnsureManagementEtcdCAPIComponentsExist(nil) test.expectUpgradeCoreComponents() + test.expectApplyServerSide(nil) test.expectPauseGitOpsReconcile(nil) test.expectBackupManagementFromCluster(nil) test.expectPauseCAPIWorkloadClusters(nil) @@ -524,6 +568,7 @@ func TestUpgradeManagementRunUpdateGitEksaSpecFailed(t *testing.T) { test.expectUpdateSecrets(nil) test.expectEnsureManagementEtcdCAPIComponentsExist(nil) test.expectUpgradeCoreComponents() + test.expectApplyServerSide(nil) test.expectPauseGitOpsReconcile(nil) test.expectBackupManagementFromCluster(nil) test.expectPauseCAPIWorkloadClusters(nil) @@ -552,6 +597,7 @@ func TestUpgradeManagementRunForceReconcileGitRepoFailed(t *testing.T) { test.expectUpdateSecrets(nil) test.expectEnsureManagementEtcdCAPIComponentsExist(nil) test.expectUpgradeCoreComponents() + test.expectApplyServerSide(nil) test.expectPauseGitOpsReconcile(nil) test.expectBackupManagementFromCluster(nil) test.expectPauseCAPIWorkloadClusters(nil) @@ -581,6 +627,7 @@ func TestUpgradeManagementRunResumeClusterResourcesReconcileFailed(t *testing.T) test.expectUpdateSecrets(nil) test.expectEnsureManagementEtcdCAPIComponentsExist(nil) test.expectUpgradeCoreComponents() + test.expectApplyServerSide(nil) test.expectPauseGitOpsReconcile(nil) test.expectBackupManagementFromCluster(nil) test.expectPauseCAPIWorkloadClusters(nil) @@ -612,6 +659,7 @@ func TestUpgradeManagementRunSuccess(t *testing.T) { test.expectUpdateSecrets(nil) test.expectEnsureManagementEtcdCAPIComponentsExist(nil) test.expectUpgradeCoreComponents() + test.expectApplyServerSide(nil) test.expectPauseGitOpsReconcile(nil) test.expectBackupManagementFromCluster(nil) test.expectPauseCAPIWorkloadClusters(nil)