From 3ab11691b314e8ebc987c2b0361f81cc8839ac52 Mon Sep 17 00:00:00 2001 From: Tanvir Tatla Date: Thu, 4 Jan 2024 16:38:23 -0800 Subject: [PATCH] applier and filewriter struct --- cmd/eksctl-anywhere/cmd/createcluster.go | 7 ++ pkg/clustermanager/cluster_creator.go | 101 +++++++++++++++++++++ pkg/task/task.go | 2 + pkg/workflows/interfaces/interfaces.go | 2 +- pkg/workflows/management/create.go | 5 + pkg/workflows/management/create_cluster.go | 18 ++-- pkg/workflows/structs/structs.go | 3 +- 7 files changed, 130 insertions(+), 8 deletions(-) create mode 100644 pkg/clustermanager/cluster_creator.go diff --git a/cmd/eksctl-anywhere/cmd/createcluster.go b/cmd/eksctl-anywhere/cmd/createcluster.go index 77146303c7fc..3524fd6c7f08 100644 --- a/cmd/eksctl-anywhere/cmd/createcluster.go +++ b/cmd/eksctl-anywhere/cmd/createcluster.go @@ -288,6 +288,12 @@ func (cc *createClusterOptions) createCluster(cmd *cobra.Command, _ []string) er if err != nil { return err } + + clusCreator := clustermanager.ClusterCreator{ + Applier: deps.ClusterApplier, + FS: deps.Writer, + } + createMgmtCluster := m.NewCreate( deps.Bootstrapper, deps.Provider, @@ -297,6 +303,7 @@ func (cc *createClusterOptions) createCluster(cmd *cobra.Command, _ []string) er deps.EksdInstaller, deps.PackageInstaller, clusterCreate, + clusCreator, ) err = createMgmtCluster.Run(ctx, clusterSpec, createValidations, cc.forceClean) diff --git a/pkg/clustermanager/cluster_creator.go b/pkg/clustermanager/cluster_creator.go new file mode 100644 index 000000000000..d070c2002141 --- /dev/null +++ b/pkg/clustermanager/cluster_creator.go @@ -0,0 +1,101 @@ +package clustermanager + +import ( + "context" + "fmt" + + corev1 "k8s.io/api/core/v1" + + "github.com/aws/eks-anywhere/pkg/cluster" + "github.com/aws/eks-anywhere/pkg/constants" + "github.com/aws/eks-anywhere/pkg/filewriter" + "github.com/aws/eks-anywhere/pkg/kubeconfig" + "github.com/aws/eks-anywhere/pkg/providers" + "github.com/aws/eks-anywhere/pkg/retrier" + "github.com/aws/eks-anywhere/pkg/types" +) + +type ClusterCreator struct { + Applier Applier + // FS is a file system abstraction providing file creation and write capabilities. + FS filewriter.FileWriter +} + +func (cc ClusterCreator) GetKubeconfig(ctx context.Context, clusterSpec *cluster.Spec, managementCluster *types.Cluster) ([]byte, error) { + kubeconfigSecret := &corev1.Secret{} + + err := retrier.New( + cc.Applier.applyClusterTimeout, + retrier.WithRetryPolicy(retrier.BackOffPolicy(cc.Applier.retryBackOff)), + ).Retry(func() error { + client, err := cc.Applier.clientFactory.BuildClientFromKubeconfig(managementCluster.KubeconfigFile) + if err != nil { + return err + } + + err = client.Get(ctx, fmt.Sprintf("%s-kubeconfig", clusterSpec.Cluster.Name), constants.EksaSystemNamespace, kubeconfigSecret) + + if err != nil { + return err + } + + return nil + }) + + if err != nil { + return nil, err + } + + return kubeconfigSecret.Data["value"], nil +} + +func (cc ClusterCreator) CreateSync(ctx context.Context, spec *cluster.Spec, managementCluster *types.Cluster, provider providers.Provider) (*types.Cluster, error) { + err := cc.Applier.Run(ctx, spec, *managementCluster) + if err != nil { + return nil, err + } + + return cc.getWorkloadCluster(ctx, spec, managementCluster, provider) +} + +func (cc ClusterCreator) getWorkloadCluster(ctx context.Context, clusterSpec *cluster.Spec, management *types.Cluster, provider providers.Provider) (*types.Cluster, error) { + clusterName := clusterSpec.Cluster.Name + + workloadCluster := &types.Cluster{ + Name: clusterName, + ExistingManagement: management.ExistingManagement, + } + + rawkubeconfig, err := cc.GetKubeconfig(ctx, clusterSpec, management) + if err != nil { + return nil, err + } + + kubeconfigPath, err := cc.WriteKubeconfig(rawkubeconfig, clusterName, provider) + if err != nil { + return nil, err + } + workloadCluster.KubeconfigFile = kubeconfigPath + + return workloadCluster, nil +} + +func (cc ClusterCreator) WriteKubeconfig(rawkubeconfig []byte, clusterName string, provider providers.Provider) (string, error) { + err := provider.UpdateKubeConfig(&rawkubeconfig, clusterName) + if err != nil { + return "", err + } + + kubeconfigPath, err := cc.FS.Write( + kubeconfig.FormatWorkloadClusterKubeconfigFilename(clusterName), + rawkubeconfig, + filewriter.PersistentFile, + filewriter.Permission0600, + ) + + if err != nil { + return "", err + } + + return kubeconfigPath, nil +} diff --git a/pkg/task/task.go b/pkg/task/task.go index 20406bb39dc3..0e214d345784 100644 --- a/pkg/task/task.go +++ b/pkg/task/task.go @@ -10,6 +10,7 @@ import ( "sigs.k8s.io/yaml" "github.com/aws/eks-anywhere/pkg/cluster" + "github.com/aws/eks-anywhere/pkg/clustermanager" "github.com/aws/eks-anywhere/pkg/filewriter" "github.com/aws/eks-anywhere/pkg/logger" "github.com/aws/eks-anywhere/pkg/providers" @@ -39,6 +40,7 @@ type CommandContext struct { EksdUpgrader interfaces.EksdUpgrader ClusterUpgrader interfaces.ClusterUpgrader ClusterCreate structs.ClusterCreate + ClusterCreator clustermanager.ClusterCreator CAPIManager interfaces.CAPIManager ClusterSpec *cluster.Spec CurrentClusterSpec *cluster.Spec diff --git a/pkg/workflows/interfaces/interfaces.go b/pkg/workflows/interfaces/interfaces.go index ec1a34f42b48..17f496afd1ce 100644 --- a/pkg/workflows/interfaces/interfaces.go +++ b/pkg/workflows/interfaces/interfaces.go @@ -95,7 +95,7 @@ type ClusterCreator interface { Run(ctx context.Context, spec *cluster.Spec, managementCluster types.Cluster) error } -// Cluster +// Cluster represents a workload cluster to be created. type Cluster interface { WriteKubeconfig(ctx context.Context, w io.Writer, management *types.Cluster) error WaitUntilControlPlaneAvailable(ctx context.Context, management *types.Cluster) error diff --git a/pkg/workflows/management/create.go b/pkg/workflows/management/create.go index 6414c699ebe2..f2fd7231deb5 100644 --- a/pkg/workflows/management/create.go +++ b/pkg/workflows/management/create.go @@ -4,6 +4,7 @@ import ( "context" "github.com/aws/eks-anywhere/pkg/cluster" + "github.com/aws/eks-anywhere/pkg/clustermanager" "github.com/aws/eks-anywhere/pkg/filewriter" "github.com/aws/eks-anywhere/pkg/providers" "github.com/aws/eks-anywhere/pkg/task" @@ -21,6 +22,7 @@ type Create struct { eksdInstaller interfaces.EksdInstaller packageInstaller interfaces.PackageInstaller clusterCreate structs.ClusterCreate + clusterCreator clustermanager.ClusterCreator } // NewCreate builds a new create construct. @@ -29,6 +31,7 @@ func NewCreate(bootstrapper interfaces.Bootstrapper, provider providers.Provider writer filewriter.FileWriter, eksdInstaller interfaces.EksdInstaller, packageInstaller interfaces.PackageInstaller, clusterCreate structs.ClusterCreate, + clusterCreator clustermanager.ClusterCreator, ) *Create { return &Create{ bootstrapper: bootstrapper, @@ -39,6 +42,7 @@ func NewCreate(bootstrapper interfaces.Bootstrapper, provider providers.Provider eksdInstaller: eksdInstaller, packageInstaller: packageInstaller, clusterCreate: clusterCreate, + clusterCreator: clusterCreator, } } @@ -55,6 +59,7 @@ func (c *Create) Run(ctx context.Context, clusterSpec *cluster.Spec, validator i EksdInstaller: c.eksdInstaller, PackageInstaller: c.packageInstaller, ClusterCreate: c.clusterCreate, + ClusterCreator: c.clusterCreator, } return task.NewTaskRunner(&setupAndValidateCreate{}, c.writer).RunTask(ctx, commandContext) diff --git a/pkg/workflows/management/create_cluster.go b/pkg/workflows/management/create_cluster.go index 7319a14122d5..09e47ed3719f 100644 --- a/pkg/workflows/management/create_cluster.go +++ b/pkg/workflows/management/create_cluster.go @@ -76,12 +76,18 @@ func (s *createWorkloadClusterTask) Run(ctx context.Context, commandContext *tas commandContext.ClusterSpec.Cluster.AddManagedByCLIAnnotation() logger.Info("Applying cluster spec to bootstrap cluster") - if err := commandContext.ClusterCreate.ClusterCreator.Run(ctx, commandContext.ClusterSpec, *commandContext.BootstrapCluster); err != nil { - commandContext.SetError(err) - return &workflows.CollectMgmtClusterDiagnosticsTask{} - } - - workloadCluster, err := commandContext.ClusterCreate.GetWorkloadCluster(ctx, commandContext.ClusterSpec, *&commandContext.BootstrapCluster, commandContext.Provider) + // if err := commandContext.ClusterCreate.ClusterCreator.Run(ctx, commandContext.ClusterSpec, *commandContext.BootstrapCluster); err != nil { + // commandContext.SetError(err) + // return &workflows.CollectMgmtClusterDiagnosticsTask{} + // } + + // workloadCluster, err := commandContext.ClusterCreate.GetWorkloadCluster(ctx, commandContext.ClusterSpec, *&commandContext.BootstrapCluster, commandContext.Provider) + // if err != nil { + // commandContext.SetError(err) + // return &workflows.CollectDiagnosticsTask{} + // } + + workloadCluster, err := commandContext.ClusterCreator.CreateSync(ctx, commandContext.ClusterSpec, commandContext.BootstrapCluster, commandContext.Provider) if err != nil { commandContext.SetError(err) return &workflows.CollectDiagnosticsTask{} diff --git a/pkg/workflows/structs/structs.go b/pkg/workflows/structs/structs.go index 823ba0a4c507..58dd46be5953 100644 --- a/pkg/workflows/structs/structs.go +++ b/pkg/workflows/structs/structs.go @@ -13,7 +13,7 @@ import ( "github.com/aws/eks-anywhere/pkg/workflows/interfaces" ) -// ClusterCreate creates a Kubernetes conformant cluster that is immediately usable for simple workloads. +// ClusterCreate creates a Kubernetes cluster that is immediately usable for simple workloads. type ClusterCreate struct { Cluster interfaces.Cluster ClusterCreator interfaces.ClusterCreator @@ -22,6 +22,7 @@ type ClusterCreate struct { FS filewriter.FileWriter } +// GetWorkloadCluster returns the types.Cluster object for a newly created workload cluster. func (cc ClusterCreate) GetWorkloadCluster(ctx context.Context, clusterSpec *cluster.Spec, management *types.Cluster, provider providers.Provider) (*types.Cluster, error) { clusterName := clusterSpec.Cluster.Name