From 6ceaa56474c45c4afd6ed7240b7abbbc52ceba6a Mon Sep 17 00:00:00 2001 From: nimrod-up9 <59927337+nimrod-up9@users.noreply.github.com> Date: Thu, 6 May 2021 17:43:22 +0300 Subject: [PATCH] CLI cleanup (#33) * Moved cli root command to tap subcommand. * tap subcommand works. * Added view and fetch placeholders. * Updated descriptions. * Fixed indentation. * Added versio subcommand. * Removed version flag. * gofmt. * Changed pod from flag to arg. * Commented out "all namespaces" flag. --- cli/cmd/fetch.go | 19 ++++++++++++++++ cli/cmd/root.go | 39 +++++--------------------------- cli/cmd/tap.go | 42 +++++++++++++++++++++++++++++++++++ cli/cmd/version.go | 22 ++++++++++++++++++ cli/cmd/view.go | 19 ++++++++++++++++ cli/config/config.go | 18 +++++++-------- cli/kubernetes/portForward.go | 10 ++++----- cli/mizu/mizuRunner.go | 8 +++---- 8 files changed, 125 insertions(+), 52 deletions(-) create mode 100644 cli/cmd/fetch.go create mode 100644 cli/cmd/tap.go create mode 100644 cli/cmd/version.go create mode 100644 cli/cmd/view.go diff --git a/cli/cmd/fetch.go b/cli/cmd/fetch.go new file mode 100644 index 000000000..3dcb1ff00 --- /dev/null +++ b/cli/cmd/fetch.go @@ -0,0 +1,19 @@ +package cmd + +import ( + "errors" + + "github.com/spf13/cobra" +) + +var fetchCmd = &cobra.Command{ + Use: "fetch", + Short: "Download recorded traffic", + RunE: func(cmd *cobra.Command, args []string) error { + return errors.New("Not implemented") + }, +} + +func init() { + rootCmd.AddCommand(fetchCmd) +} diff --git a/cli/cmd/root.go b/cli/cmd/root.go index c807fe1ca..153983d7d 100644 --- a/cli/cmd/root.go +++ b/cli/cmd/root.go @@ -2,44 +2,17 @@ package cmd import ( "github.com/spf13/cobra" - "github.com/up9inc/mizu/cli/config" - "github.com/up9inc/mizu/cli/mizu" ) -// rootCmd represents the base command when called without any subcommands -var ( - rootCmd = &cobra.Command{} -) -func init() { - rootCmd.Use = "mizu" - rootCmd.Short = "Tail HTTP traffic from multiple pods" - rootCmd.RunE = func(cmd *cobra.Command, args []string) error { - if len(args) != 0 { - return rootCmd.Help() - } - - mizu.Run() - return nil - } - - rootCmd.Flags().BoolVarP(&config.Configuration.DisplayVersion, "version", "v", false, "Print the version and exit") - rootCmd.Flags().BoolVarP(&config.Configuration.Quiet, "quiet", "q", false, "No stdout output") - rootCmd.Flags().BoolVarP(&config.Configuration.NoDashboard, "no-dashboard", "", false, "Dont host a dashboard") - rootCmd.Flags().Uint16VarP(&config.Configuration.DashboardPort, "dashboard-port", "p", 8899, "Provide a custom port for the dashboard webserver") - rootCmd.Flags().StringVarP(&config.Configuration.Namespace, "namespace", "n", "", "Namespace selector") - rootCmd.Flags().BoolVarP(&config.Configuration.AllNamespaces, "all-namespaces", "A", false, "Select all namespaces") - rootCmd.Flags().StringVarP(&config.Configuration.KubeConfigPath, "kubeconfig", "k", "", "Path to kubeconfig file") - rootCmd.Flags().StringVarP(&config.Configuration.MizuImage, "mizu-image", "", "gcr.io/up9-docker-hub/mizu/develop:latest", "Custom image for mizu collector") - rootCmd.Flags().Uint16VarP(&config.Configuration.MizuPodPort, "mizu-port", "", 8899, "Port which mizu cli will attempt to forward from the mizu collector pod") - rootCmd.Flags().StringVarP(&config.Configuration.TappedPodName, "pod", "", "", "View traffic of this pod") - err := rootCmd.MarkFlagRequired("pod") - if err != nil { - panic(err) - } +var rootCmd = &cobra.Command{ + Use: "mizu", + Short: "A web traffic viewer for kubernetes", + Long: `A web traffic viewer for kubernetes + Further info is available at https://github.com/up9inc/mizu`, } // Execute adds all child commands to the root command and sets flags appropriately. -// This is called by main.main(). It only needs to happen once to the rootCmd. +// This is called by main.main(). It only needs to happen once to the tapCmd. func Execute() { cobra.CheckErr(rootCmd.Execute()) } diff --git a/cli/cmd/tap.go b/cli/cmd/tap.go new file mode 100644 index 000000000..4eb71244e --- /dev/null +++ b/cli/cmd/tap.go @@ -0,0 +1,42 @@ +package cmd + +import ( + "errors" + + "github.com/spf13/cobra" + + "github.com/up9inc/mizu/cli/config" + "github.com/up9inc/mizu/cli/mizu" +) + +var tapCmd = &cobra.Command{ + Use: "tap [PODNAME]", + Short: "Record ingoing traffic of a kubernetes pod", + Long: `Record the ingoing traffic of a kubernetes pod. + Supported protocols are HTTP and gRPC.`, + RunE: func(cmd *cobra.Command, args []string) error { + if len(args) == 0 { + return errors.New("PODNAME argument is required") + } else if len(args) > 1 { + return errors.New("Unexpected number of arguments") + } + + podName := args[0] + + mizu.Run(podName) + return nil + }, +} + +func init() { + rootCmd.AddCommand(tapCmd) + + tapCmd.Flags().BoolVarP(&config.Configuration.Quiet, "quiet", "q", false, "No stdout output") + tapCmd.Flags().BoolVarP(&config.Configuration.NoDashboard, "no-dashboard", "", false, "Dont host a dashboard") + tapCmd.Flags().Uint16VarP(&config.Configuration.DashboardPort, "dashboard-port", "p", 8899, "Provide a custom port for the dashboard webserver") + tapCmd.Flags().StringVarP(&config.Configuration.Namespace, "namespace", "n", "", "Namespace selector") + // tapCmd.Flags().BoolVarP(&config.Configuration.AllNamespaces, "all-namespaces", "A", false, "Select all namespaces") + tapCmd.Flags().StringVarP(&config.Configuration.KubeConfigPath, "kubeconfig", "k", "", "Path to kubeconfig file") + tapCmd.Flags().StringVarP(&config.Configuration.MizuImage, "mizu-image", "", "gcr.io/up9-docker-hub/mizu/develop:latest", "Custom image for mizu collector") + tapCmd.Flags().Uint16VarP(&config.Configuration.MizuPodPort, "mizu-port", "", 8899, "Port which mizu cli will attempt to forward from the mizu collector pod") +} diff --git a/cli/cmd/version.go b/cli/cmd/version.go new file mode 100644 index 000000000..f292153dc --- /dev/null +++ b/cli/cmd/version.go @@ -0,0 +1,22 @@ +package cmd + +import ( + "fmt" + + "github.com/spf13/cobra" +) + +var Version = "0.1.0" + +var versionCmd = &cobra.Command{ + Use: "version", + Short: "Print version info", + RunE: func(cmd *cobra.Command, args []string) error { + fmt.Printf("mizu version %s\n", Version) + return nil + }, +} + +func init() { + rootCmd.AddCommand(versionCmd) +} diff --git a/cli/cmd/view.go b/cli/cmd/view.go new file mode 100644 index 000000000..6ab02336f --- /dev/null +++ b/cli/cmd/view.go @@ -0,0 +1,19 @@ +package cmd + +import ( + "errors" + + "github.com/spf13/cobra" +) + +var viewCmd = &cobra.Command{ + Use: "view", + Short: "Open GUI in browser", + RunE: func(cmd *cobra.Command, args []string) error { + return errors.New("Not implemented") + }, +} + +func init() { + rootCmd.AddCommand(viewCmd) +} diff --git a/cli/config/config.go b/cli/config/config.go index 0b7d6ee76..d789ad31c 100644 --- a/cli/config/config.go +++ b/cli/config/config.go @@ -1,16 +1,14 @@ package config type Options struct { - DisplayVersion bool - Quiet bool - NoDashboard bool - DashboardPort uint16 - Namespace string - AllNamespaces bool - KubeConfigPath string - MizuImage string - MizuPodPort uint16 - TappedPodName string + Quiet bool + NoDashboard bool + DashboardPort uint16 + Namespace string + AllNamespaces bool + KubeConfigPath string + MizuImage string + MizuPodPort uint16 } var Configuration = &Options{} diff --git a/cli/kubernetes/portForward.go b/cli/kubernetes/portForward.go index 4c5ef480f..bc00ef8a1 100644 --- a/cli/kubernetes/portForward.go +++ b/cli/kubernetes/portForward.go @@ -25,11 +25,11 @@ func NewPortForward(kubernetesProvider *Provider, namespace string, podName stri if err != nil { return nil, err } - go func () { - err = forwarder.ForwardPorts() // this is blocking - if err != nil { - fmt.Printf("kubernetes port-forwarding error: %s", err) - cancel() + go func() { + err = forwarder.ForwardPorts() // this is blocking + if err != nil { + fmt.Printf("kubernetes port-forwarding error: %s", err) + cancel() } }() return &PortForward{stopChan: stopChan}, nil diff --git a/cli/mizu/mizuRunner.go b/cli/mizu/mizuRunner.go index 39cc4cb87..e54ec947e 100644 --- a/cli/mizu/mizuRunner.go +++ b/cli/mizu/mizuRunner.go @@ -12,14 +12,14 @@ import ( "time" ) -func Run() { +func Run(tappedPodName string) { kubernetesProvider := kubernetes.NewProvider(config.Configuration.KubeConfigPath, config.Configuration.Namespace) ctx, cancel := context.WithCancel(context.Background()) defer cancel() // cancel will be called when this function exits podName := "mizu-collector" - go createPodAndPortForward(ctx, kubernetesProvider, cancel, podName) //TODO convert this to job for built in pod ttl or have the running app handle this + go createPodAndPortForward(ctx, kubernetesProvider, cancel, podName, tappedPodName) //TODO convert this to job for built in pod ttl or have the running app handle this waitForFinish(ctx, cancel) //block until exit signal or error // TODO handle incoming traffic from tapper using a channel @@ -52,8 +52,8 @@ func watchPodsForTapping(ctx context.Context, kubernetesProvider *kubernetes.Pro } } -func createPodAndPortForward(ctx context.Context, kubernetesProvider *kubernetes.Provider, cancel context.CancelFunc, podName string) { - pod, err := kubernetesProvider.CreateMizuPod(ctx, podName, config.Configuration.MizuImage, config.Configuration.TappedPodName) +func createPodAndPortForward(ctx context.Context, kubernetesProvider *kubernetes.Provider, cancel context.CancelFunc, podName string, tappedPodName string) { + pod, err := kubernetesProvider.CreateMizuPod(ctx, podName, config.Configuration.MizuImage, tappedPodName) if err != nil { fmt.Printf("error creating pod %s", err) cancel()