You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@camel.apache.org by GitBox <gi...@apache.org> on 2018/09/21 09:28:16 UTC

[GitHub] oscerd closed pull request #111: chore(kamel): improve completion and context delete

oscerd closed pull request #111: chore(kamel): improve completion and context delete
URL: https://github.com/apache/camel-k/pull/111
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/pkg/client/cmd/completion_bash.go b/pkg/client/cmd/completion_bash.go
index 1e96624..a109e36 100644
--- a/pkg/client/cmd/completion_bash.go
+++ b/pkg/client/cmd/completion_bash.go
@@ -87,6 +87,54 @@ __kamel_kubectl_get_secret() {
         COMPREPLY=( $( compgen -W "${kubectl_out}" -- "$cur" ) )
     fi
 }
+
+__kamel_kubectl_get_integrations() {
+    local template
+    local kubectl_out
+
+    template="{{ range .items  }}{{ .metadata.name }} {{ end }}"
+
+    if kubectl_out=$(kubectl get -o template --template="${template}" integrations 2>/dev/null); then
+        COMPREPLY=( $( compgen -W "${kubectl_out}" -- "$cur" ) )
+    fi
+}
+
+__kamel_kubectl_get_integrationcontexts() {
+    local template
+    local kubectl_out
+
+    template="{{ range .items  }}{{ .metadata.name }} {{ end }}"
+
+    if kubectl_out=$(kubectl get -o template --template="${template}" integrationcontexts 2>/dev/null); then
+        COMPREPLY=( $( compgen -W "${kubectl_out}" -- "$cur" ) )
+    fi
+}
+
+__kamel_kubectl_get_user_integrationcontexts() {
+    local template
+    local kubectl_out
+
+    template="{{ range .items  }}{{ .metadata.name }} {{ end }}"
+
+    if kubectl_out=$(kubectl get -l camel.apache.org/context.type=user -o template --template="${template}" integrationcontexts 2>/dev/null); then
+        COMPREPLY=( $( compgen -W "${kubectl_out}" -- "$cur" ) )
+    fi
+}
+
+__custom_func() {
+    case ${last_command} in
+        kamel_delete)
+            __kamel_kubectl_get_integrations
+            return
+            ;;
+        kamel_context_delete)
+            __kamel_kubectl_get_user_integrationcontexts
+            return
+            ;;
+        *)
+            ;;
+    esac
+}
 `
 
 // ******************************
@@ -107,22 +155,41 @@ func newCmdCompletionBash(root *cobra.Command) *cobra.Command {
 }
 
 func configureKnownBashCompletions(command *cobra.Command) {
-	// completion support
-	dependencyFlag := command.Flag("dependency")
-	if dependencyFlag != nil {
-		dependencyFlag.Annotations = map[string][]string{
+	configureBashAnnotationForFlag(
+		command,
+		"dependency",
+		map[string][]string{
 			cobra.BashCompCustom: {"__kamel_dependency_type"},
-		}
-	}
+		},
+	)
+	configureBashAnnotationForFlag(
+		command,
+		"configmap",
+		map[string][]string{
+			cobra.BashCompCustom: {"__kamel_kubectl_get_configmap"},
+		},
+	)
+	configureBashAnnotationForFlag(
+		command,
+		"secret",
+		map[string][]string{
+			cobra.BashCompCustom: {"__kamel_kubectl_get_secret"},
+		},
+	)
+	configureBashAnnotationForFlag(
+		command,
+		"context",
+		map[string][]string{
+			cobra.BashCompCustom: {"__kamel_kubectl_get_user_integrationcontexts"},
+		},
+	)
+}
 
-	configMapFlag := command.Flag("configmap")
-	configMapFlag.Annotations = map[string][]string{
-		cobra.BashCompCustom: {"__kamel_kubectl_get_configmap"},
-	}
+func configureBashAnnotationForFlag(command *cobra.Command, flagName string, annotations map[string][]string) {
 
-	secretFlag := command.Flag("secret")
-	secretFlag.Annotations = map[string][]string{
-		cobra.BashCompCustom: {"__kamel_kubectl_get_secret"},
+	flag := command.Flag(flagName)
+	if flag != nil {
+		flag.Annotations = annotations
 	}
 }
 
diff --git a/pkg/client/cmd/context_delete.go b/pkg/client/cmd/context_delete.go
index be77d09..86e754d 100644
--- a/pkg/client/cmd/context_delete.go
+++ b/pkg/client/cmd/context_delete.go
@@ -20,11 +20,12 @@ package cmd
 import (
 	"errors"
 	"fmt"
-	"strconv"
 
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 	"github.com/operator-framework/operator-sdk/pkg/sdk"
 	"github.com/spf13/cobra"
+
+	k8errors "k8s.io/apimachinery/pkg/api/errors"
 )
 
 func newContextDeleteCmd(rootCmdOptions *RootCmdOptions) *cobra.Command {
@@ -36,45 +37,102 @@ func newContextDeleteCmd(rootCmdOptions *RootCmdOptions) *cobra.Command {
 		Use:   "delete",
 		Short: "Delete an Integration Context",
 		Long:  `Delete anIntegration Context.`,
-		Args:  impl.validateArgs,
-		RunE:  impl.run,
+		RunE: func(cmd *cobra.Command, args []string) error {
+			if err := impl.validate(cmd, args); err != nil {
+				return err
+			}
+			if err := impl.run(cmd, args); err != nil {
+				fmt.Println(err.Error())
+			}
+
+			return nil
+		},
 	}
 
+	cmd.Flags().BoolVar(&impl.all, "all", false, "Delete all integration contexts")
+
 	return &cmd
 }
 
 type contextDeleteCommand struct {
 	*RootCmdOptions
+	all bool
 }
 
-func (command *contextDeleteCommand) validateArgs(cmd *cobra.Command, args []string) error {
-	if len(args) != 1 {
-		return errors.New("accepts 1 arg, received " + strconv.Itoa(len(args)))
+func (command *contextDeleteCommand) validate(cmd *cobra.Command, args []string) error {
+	if command.all && len(args) > 0 {
+		return errors.New("invalid combination: both all flag and named contexts are set")
+	}
+	if !command.all && len(args) == 0 {
+		return errors.New("invalid combination: neither all flag nor named contexts are set")
 	}
 
 	return nil
 }
 
 func (command *contextDeleteCommand) run(cmd *cobra.Command, args []string) error {
-	ctx := v1alpha1.NewIntegrationContext(command.Namespace, args[0])
+	names := args
+
+	if command.all {
+		ctxList := v1alpha1.NewIntegrationContextList()
+		if err := sdk.List(command.Namespace, &ctxList); err != nil {
+			return err
+		}
+
+		names = make([]string, 0, len(ctxList.Items))
+		for _, item := range ctxList.Items {
+			// only include non platform contexts
+			if item.Labels["camel.apache.org/context.type"] != "platform" {
+				names = append(names, item.Name)
+			}
+		}
+	}
+
+	for _, name := range names {
+		if err := command.delete(name); err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
 
-	if err := sdk.Get(&ctx); err != nil {
+func (command *contextDeleteCommand) delete(name string) error {
+	ctx := v1alpha1.NewIntegrationContext(command.Namespace, name)
+
+	err := sdk.Get(&ctx)
+
+	// pass through if the context is not found
+	if err != nil && k8errors.IsNotFound(err) {
+		return fmt.Errorf("no integration context found with name \"%s\"", ctx.Name)
+	}
+
+	// fail otherwise
+	if err != nil {
 		return err
 	}
 
-	// let's check that it is not a platform one which is supposed to be "read only"
+	// check that it is not a platform one which is supposed to be "read only"
 	// thus not managed by the end user
 	if ctx.Labels["camel.apache.org/context.type"] == "platform" {
-		fmt.Printf("integration context \"%s\" is not editable\n", ctx.Name)
-		return nil
+		// skip platform contexts while deleting all contexts
+		if command.all {
+			return nil
+		}
+
+		return fmt.Errorf("integration context \"%s\" is not editable", ctx.Name)
 	}
 
-	if err := sdk.Delete(&ctx); err != nil {
-		fmt.Printf("error deleting integration context \"%s\", %s\n", ctx.Name, err)
-		return err
+	err = sdk.Delete(&ctx)
+
+	if err != nil && !k8errors.IsNotFound(err) {
+		return fmt.Errorf("error deleting integration context \"%s\", %s", ctx.Name, err)
+	}
+	if err != nil && k8errors.IsNotFound(err) {
+		return fmt.Errorf("no integration context found with name \"%s\"", ctx.Name)
 	}
 
 	fmt.Printf("integration context \"%s\" has been deleted\n", ctx.Name)
 
-	return nil
+	return err
 }
diff --git a/pkg/client/cmd/context_get.go b/pkg/client/cmd/context_get.go
index 0a487b2..f79bf86 100644
--- a/pkg/client/cmd/context_get.go
+++ b/pkg/client/cmd/context_get.go
@@ -28,7 +28,7 @@ import (
 )
 
 func newContextGetCmd(rootCmdOptions *RootCmdOptions) *cobra.Command {
-	options := contextGetCommand{
+	impl := contextGetCommand{
 		RootCmdOptions: rootCmdOptions,
 	}
 
@@ -36,14 +36,33 @@ func newContextGetCmd(rootCmdOptions *RootCmdOptions) *cobra.Command {
 		Use:   "get",
 		Short: "Get defined Integration Context",
 		Long:  `Get defined Integration Context.`,
-		RunE:  options.run,
+		RunE: func(cmd *cobra.Command, args []string) error {
+			if err := impl.validate(cmd, args); err != nil {
+				return err
+			}
+			if err := impl.run(cmd, args); err != nil {
+				fmt.Println(err.Error())
+			}
+
+			return nil
+		},
 	}
 
+	cmd.Flags().BoolVar(&impl.user, "user", true, "Includes user contexts")
+	cmd.Flags().BoolVar(&impl.platform, "platform", true, "Includes platform contexts")
+
 	return &cmd
 }
 
 type contextGetCommand struct {
 	*RootCmdOptions
+	user     bool
+	platform bool
+}
+
+func (command *contextGetCommand) validate(cmd *cobra.Command, args []string) error {
+	return nil
+
 }
 
 func (command *contextGetCommand) run(cmd *cobra.Command, args []string) error {
@@ -55,7 +74,13 @@ func (command *contextGetCommand) run(cmd *cobra.Command, args []string) error {
 	w := tabwriter.NewWriter(os.Stdout, 0, 8, 1, '\t', 0)
 	fmt.Fprintln(w, "NAME\tTYPE\tSTATUS")
 	for _, ctx := range ctxList.Items {
-		fmt.Fprintf(w, "%s\t%s\t%s\n", ctx.Name, ctx.Labels["camel.apache.org/context.type"], string(ctx.Status.Phase))
+		t := ctx.Labels["camel.apache.org/context.type"]
+		u := command.user && t == "user"
+		p := command.platform && t == "platform"
+
+		if u || p {
+			fmt.Fprintf(w, "%s\t%s\t%s\n", ctx.Name, t, string(ctx.Status.Phase))
+		}
 	}
 	w.Flush()
 
diff --git a/pkg/client/cmd/delete.go b/pkg/client/cmd/delete.go
index 78acfc8..2a9a0f3 100644
--- a/pkg/client/cmd/delete.go
+++ b/pkg/client/cmd/delete.go
@@ -20,7 +20,6 @@ package cmd
 import (
 	"errors"
 	"fmt"
-	"os"
 	"strconv"
 
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
@@ -32,16 +31,25 @@ import (
 
 // NewCmdDelete --
 func newCmdDelete(rootCmdOptions *RootCmdOptions) *cobra.Command {
-	options := deleteCmdOptions{
+	impl := deleteCmdOptions{
 		RootCmdOptions: rootCmdOptions,
 	}
 	cmd := cobra.Command{
 		Use:   "delete [integration1] [integration2] ...",
 		Short: "Delete integrations deployed on Kubernetes",
-		RunE:  options.run,
+		RunE: func(cmd *cobra.Command, args []string) error {
+			if err := impl.validate(cmd, args); err != nil {
+				return err
+			}
+			if err := impl.run(cmd, args); err != nil {
+				fmt.Println(err.Error())
+			}
+
+			return nil
+		},
 	}
-	cmd.Flags().BoolVar(&options.deleteAll, "all", false, "Delete all integrations")
-	cmd.ParseFlags(os.Args)
+
+	cmd.Flags().BoolVar(&impl.deleteAll, "all", false, "Delete all integrations")
 
 	return &cmd
 }
@@ -51,27 +59,29 @@ type deleteCmdOptions struct {
 	deleteAll bool
 }
 
-func (o *deleteCmdOptions) run(cmd *cobra.Command, args []string) error {
-	namespace := o.Namespace
-
-	integrationList := v1alpha1.IntegrationList{
-		TypeMeta: metav1.TypeMeta{
-			APIVersion: v1alpha1.SchemeGroupVersion.String(),
-			Kind:       v1alpha1.IntegrationKind,
-		},
+func (command *deleteCmdOptions) validate(cmd *cobra.Command, args []string) error {
+	if command.deleteAll && len(args) > 0 {
+		return errors.New("invalid combination: both all flag and named integrations are set")
 	}
+	if !command.deleteAll && len(args) == 0 {
+		return errors.New("invalid combination: neither all flag nor named integrations are set")
+	}
+
+	return nil
+}
 
-	if len(args) != 0 && !o.deleteAll {
-		i := 0
-		for i < len(args) {
+func (command *deleteCmdOptions) run(cmd *cobra.Command, args []string) error {
+
+	if len(args) != 0 && !command.deleteAll {
+		for _, arg := range args {
 			integration := v1alpha1.Integration{
 				TypeMeta: metav1.TypeMeta{
 					Kind:       v1alpha1.IntegrationKind,
 					APIVersion: v1alpha1.SchemeGroupVersion.String(),
 				},
 				ObjectMeta: metav1.ObjectMeta{
-					Namespace: namespace,
-					Name:      args[i],
+					Namespace: command.Namespace,
+					Name:      arg,
 				},
 			}
 
@@ -85,11 +95,17 @@ func (o *deleteCmdOptions) run(cmd *cobra.Command, args []string) error {
 			} else {
 				fmt.Println("Integration " + integration.GetName() + " deleted")
 			}
-			i++
 		}
-	} else if o.deleteAll {
+	} else if command.deleteAll {
+		integrationList := v1alpha1.IntegrationList{
+			TypeMeta: metav1.TypeMeta{
+				APIVersion: v1alpha1.SchemeGroupVersion.String(),
+				Kind:       v1alpha1.IntegrationKind,
+			},
+		}
+
 		//Looks like Operator SDK doesn't support deletion of all objects with one command
-		err := sdk.List(namespace, &integrationList)
+		err := sdk.List(command.Namespace, &integrationList)
 		if err != nil {
 			return err
 		}
@@ -104,10 +120,6 @@ func (o *deleteCmdOptions) run(cmd *cobra.Command, args []string) error {
 		} else {
 			fmt.Println(strconv.Itoa(len(integrationList.Items)) + " integration(s) deleted")
 		}
-	} else {
-		err := errors.New("The integration name(s) or --all option must be specified")
-		return err
-
 	}
 
 	return nil


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services