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.
This commit is contained in:
nimrod-up9 2021-05-06 17:43:22 +03:00 committed by GitHub
parent c7a20ed9c0
commit 6ceaa56474
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 125 additions and 52 deletions

19
cli/cmd/fetch.go Normal file
View File

@ -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)
}

View File

@ -2,44 +2,17 @@ package cmd
import ( import (
"github.com/spf13/cobra" "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{
var ( Use: "mizu",
rootCmd = &cobra.Command{} Short: "A web traffic viewer for kubernetes",
) Long: `A web traffic viewer for kubernetes
func init() { Further info is available at https://github.com/up9inc/mizu`,
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)
}
} }
// Execute adds all child commands to the root command and sets flags appropriately. // 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() { func Execute() {
cobra.CheckErr(rootCmd.Execute()) cobra.CheckErr(rootCmd.Execute())
} }

42
cli/cmd/tap.go Normal file
View File

@ -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")
}

22
cli/cmd/version.go Normal file
View File

@ -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)
}

19
cli/cmd/view.go Normal file
View File

@ -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)
}

View File

@ -1,16 +1,14 @@
package config package config
type Options struct { type Options struct {
DisplayVersion bool Quiet bool
Quiet bool NoDashboard bool
NoDashboard bool DashboardPort uint16
DashboardPort uint16 Namespace string
Namespace string AllNamespaces bool
AllNamespaces bool KubeConfigPath string
KubeConfigPath string MizuImage string
MizuImage string MizuPodPort uint16
MizuPodPort uint16
TappedPodName string
} }
var Configuration = &Options{} var Configuration = &Options{}

View File

@ -25,11 +25,11 @@ func NewPortForward(kubernetesProvider *Provider, namespace string, podName stri
if err != nil { if err != nil {
return nil, err return nil, err
} }
go func () { go func() {
err = forwarder.ForwardPorts() // this is blocking err = forwarder.ForwardPorts() // this is blocking
if err != nil { if err != nil {
fmt.Printf("kubernetes port-forwarding error: %s", err) fmt.Printf("kubernetes port-forwarding error: %s", err)
cancel() cancel()
} }
}() }()
return &PortForward{stopChan: stopChan}, nil return &PortForward{stopChan: stopChan}, nil

View File

@ -12,14 +12,14 @@ import (
"time" "time"
) )
func Run() { func Run(tappedPodName string) {
kubernetesProvider := kubernetes.NewProvider(config.Configuration.KubeConfigPath, config.Configuration.Namespace) kubernetesProvider := kubernetes.NewProvider(config.Configuration.KubeConfigPath, config.Configuration.Namespace)
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
defer cancel() // cancel will be called when this function exits defer cancel() // cancel will be called when this function exits
podName := "mizu-collector" 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 waitForFinish(ctx, cancel) //block until exit signal or error
// TODO handle incoming traffic from tapper using a channel // 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) { func createPodAndPortForward(ctx context.Context, kubernetesProvider *kubernetes.Provider, cancel context.CancelFunc, podName string, tappedPodName string) {
pod, err := kubernetesProvider.CreateMizuPod(ctx, podName, config.Configuration.MizuImage, config.Configuration.TappedPodName) pod, err := kubernetesProvider.CreateMizuPod(ctx, podName, config.Configuration.MizuImage, tappedPodName)
if err != nil { if err != nil {
fmt.Printf("error creating pod %s", err) fmt.Printf("error creating pod %s", err)
cancel() cancel()