From 700e081cd0d438a9cc868ecdab4686efb4115ad7 Mon Sep 17 00:00:00 2001 From: Hanshal Mehta <122217807+hanshal101@users.noreply.github.com> Date: Sun, 8 Sep 2024 14:41:48 +0530 Subject: [PATCH] feat(cli): create namespace if necessary when installing a namespace-scoped package Signed-off-by: hanshal101 <122217807+hanshal101@users.noreply.github.com> --- cmd/glasskube/cmd/install.go | 27 ++++++++++++++++--------- internal/namespaces/ultils.go | 38 +++++++++++++++++++++++++++++++++++ pkg/install/install.go | 37 ---------------------------------- 3 files changed, 55 insertions(+), 47 deletions(-) create mode 100644 internal/namespaces/ultils.go diff --git a/cmd/glasskube/cmd/install.go b/cmd/glasskube/cmd/install.go index f93a37ea7..3858a96d9 100644 --- a/cmd/glasskube/cmd/install.go +++ b/cmd/glasskube/cmd/install.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/glasskube/glasskube/internal/clientutils" + "github.com/glasskube/glasskube/internal/namespaces" "github.com/fatih/color" "github.com/glasskube/glasskube/api/v1alpha1" @@ -52,13 +53,13 @@ var installCmd = &cobra.Command{ ValidArgsFunction: completeAvailablePackageNames, Run: func(cmd *cobra.Command, args []string) { ctx := cmd.Context() - cfg := clicontext.ConfigFromContext(ctx) config := clicontext.RawConfigFromContext(ctx) pkgClient := clicontext.PackageClientFromContext(ctx) dm := cliutils.DependencyManager(ctx) valueResolver := cliutils.ValueResolver(ctx) repoClientset := cliutils.RepositoryClientset(ctx) installer := install.NewInstaller(pkgClient) + cs := clicontext.KubernetesClientFromContext(ctx) opts := metav1.CreateOptions{} if installCmdOptions.DryRun { @@ -221,15 +222,27 @@ var installCmd = &cobra.Command{ } if installCmdOptions.NamespaceOptions.Namespace != "" { - _, err := install.IsNamespaceInstalled( + exists, err := namespaces.IsNamespaceInstalled( ctx, - cfg, + cs, installCmdOptions.NamespaceOptions.Namespace, ) - if errors.IsNotFound(err) { + if errors.IsNotFound(err) && !exists { fmt.Printf(" * Namespace %v does not exist and will be created", installCmdOptions.NamespaceOptions.Namespace, ) + err := namespaces.InstallNamespace( + ctx, + cs, + installCmdOptions.NamespaceOptions.Namespace, + ) + if err != nil { + fmt.Fprintf(os.Stderr, "An error occurred in creating the Namespace:\n\n%v\n", err) + cliutils.ExitWithError() + } + } else if err != nil { + fmt.Fprintf(os.Stderr, "An error occurred in the Namespace check:\n\n%v\n", err) + cliutils.ExitWithError() } } @@ -245,12 +258,6 @@ var installCmd = &cobra.Command{ cancel() } - err := install.InstallNamespace(ctx, cfg, installCmdOptions.NamespaceOptions.Namespace) - if err != nil { - fmt.Fprintf(os.Stderr, "An error occurred in creating the Namespace:\n\n%v\n", err) - cliutils.ExitWithError() - } - if installCmdOptions.NoWait { if err := installer.Install(ctx, pkg, opts); err != nil { fmt.Fprintf(os.Stderr, "An error occurred during installation:\n\n%v\n", err) diff --git a/internal/namespaces/ultils.go b/internal/namespaces/ultils.go new file mode 100644 index 000000000..046485d89 --- /dev/null +++ b/internal/namespaces/ultils.go @@ -0,0 +1,38 @@ +package namespaces + +import ( + "context" + + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" +) + +func IsNamespaceInstalled(ctx context.Context, cs *kubernetes.Clientset, namespace string) (bool, error) { + _, err := cs.CoreV1().Namespaces().Get(ctx, namespace, metav1.GetOptions{}) + if err != nil { + if errors.IsNotFound(err) { + return false, nil + } else { + return false, err + } + } + + return true, nil +} + +func InstallNamespace(ctx context.Context, cs *kubernetes.Clientset, namespace string) error { + ns := &v1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespace, + }, + } + + _, err := cs.CoreV1().Namespaces().Create(ctx, ns, metav1.CreateOptions{}) + if err != nil { + return err + } + + return nil +} diff --git a/pkg/install/install.go b/pkg/install/install.go index bc5715241..33bc42235 100644 --- a/pkg/install/install.go +++ b/pkg/install/install.go @@ -10,11 +10,8 @@ import ( "github.com/glasskube/glasskube/pkg/client" "github.com/glasskube/glasskube/pkg/condition" "github.com/glasskube/glasskube/pkg/statuswriter" - v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/watch" - "k8s.io/client-go/kubernetes" - "k8s.io/client-go/rest" ) type installer struct { @@ -117,37 +114,3 @@ func (i *installer) watch(ctx context.Context, pkg ctrlpkg.Package) (watch.Inter return nil, fmt.Errorf("unexpected package type: %T", pkg) } } - -func IsNamespaceInstalled(ctx context.Context, cfg *rest.Config, namespace string) (bool, error) { - cs, err := kubernetes.NewForConfig(cfg) - if err != nil { - return false, err - } - - _, err = cs.CoreV1().Namespaces().Get(ctx, namespace, metav1.GetOptions{}) - if err != nil { - return false, err - } - - return true, nil -} - -func InstallNamespace(ctx context.Context, cfg *rest.Config, namespace string) error { - cs, err := kubernetes.NewForConfig(cfg) - if err != nil { - return err - } - - ns := &v1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: namespace, - }, - } - - _, err = cs.CoreV1().Namespaces().Create(ctx, ns, metav1.CreateOptions{}) - if err != nil { - return err - } - - return nil -}