Skip to content

Commit

Permalink
create namespace using client factory
Browse files Browse the repository at this point in the history
  • Loading branch information
tatlat committed Feb 15, 2024
1 parent 253ac63 commit d9d7928
Show file tree
Hide file tree
Showing 13 changed files with 236 additions and 32 deletions.
2 changes: 2 additions & 0 deletions cmd/eksctl-anywhere/cmd/createcluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ func (cc *createClusterOptions) createCluster(cmd *cobra.Command, _ []string) er
deps.EksdInstaller,
deps.PackageInstaller,
deps.ClusterCreator,
deps.UnAuthKubectlClient,
)
err = createWorkloadCluster.Run(ctx, clusterSpec, createValidations)

Expand All @@ -278,6 +279,7 @@ func (cc *createClusterOptions) createCluster(cmd *cobra.Command, _ []string) er

createMgmtCluster := management.NewCreate(
deps.Bootstrapper,
deps.UnAuthKubeClient,
deps.Provider,
deps.ClusterManager,
deps.GitOpsFlux,
Expand Down
5 changes: 0 additions & 5 deletions pkg/clustermanager/cluster_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -1403,11 +1403,6 @@ func (c *ClusterManager) DeletePackageResources(ctx context.Context, managementC
return c.clusterClient.DeletePackageResources(ctx, managementCluster, clusterName)
}

// CreateNamespace creates a namespace on the target cluster if it does not already exist.
func (c *ClusterManager) CreateNamespace(ctx context.Context, targetCluster *types.Cluster, namespace string) error {
return c.clusterClient.CreateNamespaceIfNotPresent(ctx, targetCluster.KubeconfigFile, namespace)
}

func (c *ClusterManager) getUpgraderImagesFromBundle(ctx context.Context, cluster *types.Cluster, cl *cluster.Spec) (*corev1.ConfigMap, error) {
upgraderImages := make(map[string]string)
for _, versionBundle := range cl.Bundles.Spec.VersionsBundles {
Expand Down
50 changes: 50 additions & 0 deletions pkg/workflows/create_prep.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package workflows

import (
"context"

corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/aws/eks-anywhere/pkg/workflows/interfaces"
)

// CreateNamespaceIfNotPresent creates the namespace on the cluster if it does not already exist.
func CreateNamespaceIfNotPresent(ctx context.Context, namespace, kubeconfig string, clientFactory interfaces.ClientFactory) error {
client, err := clientFactory.BuildClientFromKubeconfig(kubeconfig)
if err != nil {
return err
}

namespaces := &corev1.NamespaceList{Items: []corev1.Namespace{{ObjectMeta: metav1.ObjectMeta{Name: "default"}}}}
if err := client.List(ctx, namespaces); err != nil {
return err
}

var found = false

Check failure on line 24 in pkg/workflows/create_prep.go

View workflow job for this annotation

GitHub Actions / lint

File is not `gofumpt`-ed (gofumpt)
for _, ns := range namespaces.Items {
if ns.Name == namespace {
found = true
}
}

if found {
return nil
}

ns := &corev1.Namespace{
TypeMeta: metav1.TypeMeta{
APIVersion: "v1",
Kind: "Namespace",
},
ObjectMeta: metav1.ObjectMeta{
Name: namespace,
},
}

if err = client.Create(ctx, ns); err != nil {
return err
}

return nil
}
121 changes: 121 additions & 0 deletions pkg/workflows/create_prep_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package workflows_test

import (
"context"
"fmt"
"testing"

"github.com/golang/mock/gomock"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

clientmocks "github.com/aws/eks-anywhere/pkg/clients/kubernetes/mocks"
"github.com/aws/eks-anywhere/pkg/workflows"
"github.com/aws/eks-anywhere/pkg/workflows/interfaces/mocks"
)

type createPrepTestSetup struct {
t *testing.T
ctx context.Context
client *clientmocks.MockClient
clientFactory *mocks.MockClientFactory
}

func newCreatePrepTest(t *testing.T) *createPrepTestSetup {
mockCtrl := gomock.NewController(t)
client := clientmocks.NewMockClient(mockCtrl)
clientFactory := mocks.NewMockClientFactory(mockCtrl)

return &createPrepTestSetup{
t: t,
ctx: context.Background(),
client: client,
clientFactory: clientFactory,
}
}

func newNamespace(name string) *corev1.Namespace {
return &corev1.Namespace{
TypeMeta: metav1.TypeMeta{
APIVersion: "v1",
Kind: "Namespace",
},
ObjectMeta: metav1.ObjectMeta{
Name: name,
},
}
}

func TestCreateNamespaceSuccess(t *testing.T) {
test := newCreatePrepTest(t)
kubeconfig := "testpath"
namespace := "test-ns"

test.clientFactory.EXPECT().BuildClientFromKubeconfig(kubeconfig).Return(test.client, nil)
test.client.EXPECT().List(test.ctx, gomock.AssignableToTypeOf(&corev1.NamespaceList{})).Return(nil)
test.client.EXPECT().Create(test.ctx, newNamespace(namespace)).Return(nil)

err := workflows.CreateNamespaceIfNotPresent(test.ctx, namespace, kubeconfig, test.clientFactory)
if err != nil {
t.Fatalf("Expected nil, but got %v", err)
}
}

func TestCreateNamespaceAlreadyExists(t *testing.T) {
test := newCreatePrepTest(t)
kubeconfig := "testpath"
namespace := "default"

test.clientFactory.EXPECT().BuildClientFromKubeconfig(kubeconfig).Return(test.client, nil)
test.client.EXPECT().List(test.ctx, gomock.AssignableToTypeOf(&corev1.NamespaceList{})).Return(nil)

err := workflows.CreateNamespaceIfNotPresent(test.ctx, namespace, kubeconfig, test.clientFactory)
if err != nil {
t.Fatalf("Expected nil, but got %v", err)
}
}

func TestCreateNamespaceBuildClientFail(t *testing.T) {
test := newCreatePrepTest(t)
kubeconfig := "testpath"
namespace := "test-ns"

test.clientFactory.EXPECT().BuildClientFromKubeconfig(kubeconfig).Return(test.client, fmt.Errorf(""))

err := workflows.CreateNamespaceIfNotPresent(test.ctx, namespace, kubeconfig, test.clientFactory)

if err == nil {
t.Fatalf("Expected error, but got nil")
}
}

func TestCreateNamespaceGetNamespaceFail(t *testing.T) {
test := newCreatePrepTest(t)
kubeconfig := "testpath"
namespace := "test-ns"

test.clientFactory.EXPECT().BuildClientFromKubeconfig(kubeconfig).Return(test.client, nil)
test.client.EXPECT().List(test.ctx, &corev1.NamespaceList{}).Return(fmt.Errorf(""))

err := workflows.CreateNamespaceIfNotPresent(test.ctx, namespace, kubeconfig, test.clientFactory)

if err == nil {
t.Fatalf("Expected error, but got nil")
}
}

func TestCreateNamespaceFail(t *testing.T) {
test := newCreatePrepTest(t)
kubeconfig := "testpath"
namespace := "test-ns"

test.clientFactory.EXPECT().BuildClientFromKubeconfig(kubeconfig).Return(test.client, nil)
test.client.EXPECT().List(test.ctx, &corev1.NamespaceList{}).Return(nil)
test.client.EXPECT().Create(test.ctx, newNamespace(namespace)).Return(fmt.Errorf(""))

err := workflows.CreateNamespaceIfNotPresent(test.ctx, namespace, kubeconfig, test.clientFactory)

if err == nil {
t.Fatalf("Expected error, but got nil")
}
}
1 change: 0 additions & 1 deletion pkg/workflows/interfaces/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ type ClusterManager interface {
GenerateIamAuthKubeconfig(ctx context.Context, management, workload *types.Cluster, spec *cluster.Spec) error
DeletePackageResources(ctx context.Context, managementCluster *types.Cluster, clusterName string) error
CreateRegistryCredSecret(ctx context.Context, mgmt *types.Cluster) error
CreateNamespace(ctx context.Context, targetCluster *types.Cluster, namespace string) error
}

type GitOpsManager interface {
Expand Down
14 changes: 0 additions & 14 deletions pkg/workflows/interfaces/mocks/clients.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion pkg/workflows/management/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ 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
Expand All @@ -24,7 +25,8 @@ type Create struct {
}

// NewCreate builds a new create construct.
func NewCreate(bootstrapper interfaces.Bootstrapper, provider providers.Provider,
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,
Expand All @@ -33,6 +35,7 @@ func NewCreate(bootstrapper interfaces.Bootstrapper, provider providers.Provider
) *Create {
return &Create{
bootstrapper: bootstrapper,
clientFactory: clientFactory,
provider: provider,
clusterManager: clusterManager,
gitOpsManager: gitOpsManager,
Expand All @@ -48,6 +51,7 @@ func NewCreate(bootstrapper interfaces.Bootstrapper, provider providers.Provider
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,
Expand Down
2 changes: 1 addition & 1 deletion pkg/workflows/management/create_install_eksa.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func (s *installEksaComponentsOnWorkloadTask) Run(ctx context.Context, commandCo
commandContext.ClusterSpec.Cluster.SetManagementComponentsVersion(commandContext.ClusterSpec.EKSARelease.Spec.Version)

if commandContext.ClusterSpec.Cluster.Namespace != "" {
if err := commandContext.ClusterManager.CreateNamespace(ctx, commandContext.WorkloadCluster, commandContext.ClusterSpec.Cluster.Namespace); err != nil {
if err := workflows.CreateNamespaceIfNotPresent(ctx, commandContext.ClusterSpec.Cluster.Namespace, commandContext.WorkloadCluster.KubeconfigFile, commandContext.ClientFactory); err != nil {
commandContext.SetError(err)
return &workflows.CollectMgmtClusterDiagnosticsTask{}
}
Expand Down
Loading

0 comments on commit d9d7928

Please sign in to comment.