Skip to content

Commit

Permalink
add eksa management version annotation to management cluster
Browse files Browse the repository at this point in the history
  • Loading branch information
eks-distro-pr-bot committed Jan 19, 2024
1 parent 18094e9 commit c74c29f
Show file tree
Hide file tree
Showing 18 changed files with 446 additions and 11 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,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
${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
${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
Expand Down
1 change: 1 addition & 0 deletions cmd/eksctl-anywhere/cmd/createcluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ func (cc *createClusterOptions) createCluster(cmd *cobra.Command, _ []string) er
}

createCluster := workflows.NewCreate(
deps.UnAuthKubeClient,
deps.Bootstrapper,
deps.Provider,
deps.ClusterManager,
Expand Down
1 change: 1 addition & 0 deletions cmd/eksctl-anywhere/cmd/upgradecluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ func (uc *upgradeClusterOptions) upgradeCluster(cmd *cobra.Command, args []strin

if clusterConfig.IsSelfManaged() {
upgrade := management.NewUpgrade(
deps.UnAuthKubeClient,

Check warning on line 206 in cmd/eksctl-anywhere/cmd/upgradecluster.go

View check run for this annotation

Codecov / codecov/patch

cmd/eksctl-anywhere/cmd/upgradecluster.go#L206

Added line #L206 was not covered by tests
deps.Provider,
deps.CAPIManager,
deps.ClusterManager,
Expand Down
1 change: 1 addition & 0 deletions cmd/eksctl-anywhere/cmd/upgrademanagementcomponents.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ var upgradeManagementComponentsCmd = &cobra.Command{
defer close(cmd.Context(), deps)

runner := management.NewUpgradeManagementComponentsRunner(
deps.UnAuthKubeClient,

Check warning on line 74 in cmd/eksctl-anywhere/cmd/upgrademanagementcomponents.go

View check run for this annotation

Codecov / codecov/patch

cmd/eksctl-anywhere/cmd/upgrademanagementcomponents.go#L74

Added line #L74 was not covered by tests
deps.Provider,
deps.CAPIManager,
deps.ClusterManager,
Expand Down
2 changes: 1 addition & 1 deletion internal/test/testdata.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func EKSARelease() *releasev1.EKSARelease {
},
Spec: releasev1.EKSAReleaseSpec{
ReleaseDate: "",
Version: "",
Version: "v0.0.0-dev",
GitCommit: "",
BundleManifestURL: "",
BundlesRef: releasev1.BundlesRef{
Expand Down
16 changes: 16 additions & 0 deletions pkg/api/v1alpha1/cluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -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/management-components-version"

// defaultEksaNamespace is the default namespace for EKS-A resources when not specified.
defaultEksaNamespace = "default"

Expand Down Expand Up @@ -1294,6 +1299,17 @@ func (c *Cluster) ControlPlaneAnnotation() string {
return controlPlaneAnnotation
}

// SetManagementComponentsVersion sets the `management-components version` annotation on the Cluster object.
func (c *Cluster) SetManagementComponentsVersion(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 {
Expand Down
33 changes: 33 additions & 0 deletions pkg/api/v1alpha1/cluster_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3230,3 +3230,36 @@ func TestValidateCluster(t *testing.T) {
})
}
}

func TestCluster_SetManagmentComponentsVersion(t *testing.T) {
testCases := []struct {
name string
cluster *v1alpha1.Cluster
managementComponentsVersion string
wantManagementComponentsVersion string
wantAnnotations map[string]string
}{
{
name: "self-managed cluster",
cluster: baseCluster(),
managementComponentsVersion: "v0.0.0-dev+build.0000",
wantAnnotations: map[string]string{"anywhere.eks.amazonaws.com/management-components-version": "v0.0.0-dev+build.0000"},
},
{
name: "managed cluster",
cluster: baseCluster(func(c *v1alpha1.Cluster) {
c.SetManagedBy("mgmt-cluster")
}),
managementComponentsVersion: "v0.0.0-dev+build.0000",
wantAnnotations: map[string]string{"anywhere.eks.amazonaws.com/managed-by": "mgmt-cluster"},
},
}

for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
g := NewWithT(t)
tt.cluster.SetManagementComponentsVersion(tt.managementComponentsVersion)
g.Expect(tt.cluster.Annotations).To(Equal(tt.wantAnnotations))
})
}
}
3 changes: 3 additions & 0 deletions pkg/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,6 @@ const (
Upgrade Operation = 1
Delete Operation = 2
)

// EKSACLIFieldManager is the owner name for fields applied by the EKS-A CLI.
const EKSACLIFieldManager = "eks-a-cli"
1 change: 1 addition & 0 deletions pkg/task/task.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ type Task interface {

// Command context maintains the mutable and shared entities.
type CommandContext struct {
ClientFactory interfaces.ClientFactory
Bootstrapper interfaces.Bootstrapper
Provider providers.Provider
ClusterManager interfaces.ClusterManager
Expand Down
24 changes: 23 additions & 1 deletion pkg/workflows/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -17,6 +18,7 @@ import (
)

type Create struct {
clientFactory interfaces.ClientFactory
bootstrapper interfaces.Bootstrapper
provider providers.Provider
clusterManager interfaces.ClusterManager
Expand All @@ -26,12 +28,14 @@ type Create struct {
packageInstaller interfaces.PackageInstaller
}

func NewCreate(bootstrapper interfaces.Bootstrapper, provider providers.Provider,
// NewCreate returns a Create instance.
func NewCreate(clientFactory interfaces.ClientFactory, bootstrapper interfaces.Bootstrapper, provider providers.Provider,
clusterManager interfaces.ClusterManager, gitOpsManager interfaces.GitOpsManager,
writer filewriter.FileWriter, eksdInstaller interfaces.EksdInstaller,
packageInstaller interfaces.PackageInstaller,
) *Create {
return &Create{
clientFactory: clientFactory,
bootstrapper: bootstrapper,
provider: provider,
clusterManager: clusterManager,
Expand All @@ -51,6 +55,7 @@ func (c *Create) Run(ctx context.Context, clusterSpec *cluster.Spec, validator i
}
}
commandContext := &task.CommandContext{
ClientFactory: c.clientFactory,
Bootstrapper: c.bootstrapper,
Provider: c.provider,
ClusterManager: c.clusterManager,
Expand Down Expand Up @@ -372,6 +377,23 @@ func (s *InstallEksaComponentsTask) Run(ctx context.Context, commandContext *tas
commandContext.SetError(err)
return &CollectDiagnosticsTask{}
}

client, err := commandContext.ClientFactory.BuildClientFromKubeconfig(targetCluster.KubeconfigFile)
if err != nil {
commandContext.SetError(err)
return &CollectDiagnosticsTask{}
}

commandContext.ClusterSpec.Cluster.SetManagementComponentsVersion(commandContext.ClusterSpec.EKSARelease.Spec.Version)
if err := client.ApplyServerSide(ctx,
constants.EKSACLIFieldManager,
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)
Expand Down
112 changes: 111 additions & 1 deletion pkg/workflows/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ 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"
"github.com/aws/eks-anywhere/pkg/constants"
writermocks "github.com/aws/eks-anywhere/pkg/filewriter/mocks"
"github.com/aws/eks-anywhere/pkg/providers"
providermocks "github.com/aws/eks-anywhere/pkg/providers/mocks"
Expand All @@ -23,6 +26,8 @@ import (

type createTestSetup struct {
t *testing.T
client *clientmocks.MockClient
clientFactory *mocks.MockClientFactory
packageInstaller *mocks.MockPackageInstaller
bootstrapper *mocks.MockBootstrapper
clusterManager *mocks.MockClusterManager
Expand All @@ -43,6 +48,8 @@ type createTestSetup struct {

func newCreateTest(t *testing.T) *createTestSetup {
mockCtrl := gomock.NewController(t)
client := clientmocks.NewMockClient(mockCtrl)
clientFactory := mocks.NewMockClientFactory(mockCtrl)
bootstrapper := mocks.NewMockBootstrapper(mockCtrl)
clusterManager := mocks.NewMockClusterManager(mockCtrl)
gitOpsManager := mocks.NewMockGitOpsManager(mockCtrl)
Expand All @@ -53,11 +60,13 @@ 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(clientFactory, bootstrapper, provider, clusterManager, gitOpsManager, writer, eksd, packageInstaller)
validator := mocks.NewMockValidator(mockCtrl)

return &createTestSetup{
t: t,
client: client,
clientFactory: clientFactory,
bootstrapper: bootstrapper,
clusterManager: clusterManager,
gitOpsManager: gitOpsManager,
Expand Down Expand Up @@ -202,6 +211,15 @@ func (c *createTestSetup) expectInstallEksaComponents() {
c.eksd.EXPECT().InstallEksdManifest(
c.ctx, c.clusterSpec, c.workloadCluster),

c.clientFactory.EXPECT().BuildClientFromKubeconfig(c.workloadCluster.KubeconfigFile).Return(c.client, nil),

c.client.EXPECT().ApplyServerSide(
c.ctx,
constants.EKSACLIFieldManager,
c.clusterSpec.Cluster,
kubernetes.ApplyServerSideOptions{ForceOwnership: true},
),

c.clusterManager.EXPECT().ResumeEKSAControllerReconcile(c.ctx, c.workloadCluster, c.clusterSpec, c.provider),
)
}
Expand All @@ -224,6 +242,15 @@ func (c *createTestSetup) skipInstallEksaComponents() {
c.eksd.EXPECT().InstallEksdManifest(
c.ctx, c.clusterSpec, c.bootstrapCluster),

c.clientFactory.EXPECT().BuildClientFromKubeconfig(c.bootstrapCluster.KubeconfigFile).Return(c.client, nil),

c.client.EXPECT().ApplyServerSide(
c.ctx,
constants.EKSACLIFieldManager,
c.clusterSpec.Cluster,
kubernetes.ApplyServerSideOptions{ForceOwnership: true},
),

c.clusterManager.EXPECT().ResumeEKSAControllerReconcile(c.ctx, c.bootstrapCluster, c.clusterSpec, c.provider),
)
}
Expand Down Expand Up @@ -293,6 +320,89 @@ func TestCreateRunSuccess(t *testing.T) {
}
}

func TestCreateRunInstallEksaComponentsBuildClientFailure(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.clientFactory.EXPECT().BuildClientFromKubeconfig(test.workloadCluster.KubeconfigFile).Return(nil, 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 TestCreateRunInstallEksaComponentsApplyServerSideFailure(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.clientFactory.EXPECT().BuildClientFromKubeconfig(test.workloadCluster.KubeconfigFile).Return(test.client, nil),

test.client.EXPECT().ApplyServerSide(
test.ctx,
constants.EKSACLIFieldManager,
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)
Expand Down
7 changes: 7 additions & 0 deletions pkg/workflows/interfaces/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,20 @@ import (
"context"

"github.com/aws/eks-anywhere/pkg/bootstrapper"
"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/providers"
"github.com/aws/eks-anywhere/pkg/types"
"github.com/aws/eks-anywhere/pkg/validations"
)

// ClientFactory builds Kubernetes clients.
type ClientFactory interface {
// BuildClientFromKubeconfig builds a Kubernetes client from a kubeconfig file.
BuildClientFromKubeconfig(kubeconfigPath string) (kubernetes.Client, error)
}

type Bootstrapper interface {
CreateBootstrapCluster(ctx context.Context, clusterSpec *cluster.Spec, opts ...bootstrapper.BootstrapClusterOption) (*types.Cluster, error)
DeleteBootstrapCluster(context.Context, *types.Cluster, constants.Operation, bool) error
Expand Down
Loading

0 comments on commit c74c29f

Please sign in to comment.