package cmd import ( "fmt" "regexp" "github.com/fatih/color" pkgcmd "github.com/linkerd/linkerd2/pkg/cmd" "github.com/linkerd/linkerd2/pkg/healthcheck" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) const ( // ExtensionName is the value that the viz extension resources should be labeled with ExtensionName = "viz" // LegacyExtensionName is the value that the viz extension resources were labeled with // until 15d1809bd043192bb21cacbc96112cce35bf384f LegacyExtensionName = "linkerd-viz" vizChartName = "linkerd-viz" defaultNamespace = "linkerd-viz" defaultLinkerdNamespace = "linkerd" maxRps = 100.0 jsonOutput = healthcheck.JSONOutput tableOutput = healthcheck.TableOutput wideOutput = healthcheck.WideOutput jsonPathOutput = "jsonpath" ) var ( // special handling for Windows, on all other platforms these resolve to // os.Stdout and os.Stderr, thanks to https://github.com/mattn/go-colorable stdout = color.Output stderr = color.Error apiAddr string // An empty value means "use the Kubernetes configuration" controlPlaneNamespace string kubeconfigPath string kubeContext string vizNamespace string impersonate string impersonateGroup []string verbose bool // These regexs are not as strict as they could be, but are a quick and dirty // sanity check against illegal characters. alphaNumDash = regexp.MustCompile(`^[a-zA-Z0-9-]+$`) ) // NewCmdViz returns a new jaeger command func NewCmdViz() *cobra.Command { vizCmd := &cobra.Command{ Use: "viz", Short: "viz manages the linkerd-viz extension of Linkerd service mesh", Long: `viz manages the linkerd-viz extension of Linkerd service mesh.`, PersistentPreRunE: func(cmd *cobra.Command, args []string) error { // enable / disable logging if verbose { log.SetLevel(log.DebugLevel) } else { log.SetLevel(log.PanicLevel) } if !alphaNumDash.MatchString(controlPlaneNamespace) { return fmt.Errorf("%s is not a valid namespace", controlPlaneNamespace) } return nil }, } vizCmd.PersistentFlags().StringVarP(&controlPlaneNamespace, "linkerd-namespace", "L", defaultLinkerdNamespace, "Namespace in which Linkerd is installed") vizCmd.PersistentFlags().StringVar(&kubeconfigPath, "kubeconfig", "", "Path to the kubeconfig file to use for CLI requests") vizCmd.PersistentFlags().StringVar(&kubeContext, "context", "", "Name of the kubeconfig context to use") vizCmd.PersistentFlags().StringVar(&impersonate, "as", "", "Username to impersonate for Kubernetes operations") vizCmd.PersistentFlags().StringArrayVar(&impersonateGroup, "as-group", []string{}, "Group to impersonate for Kubernetes operations") vizCmd.PersistentFlags().StringVar(&apiAddr, "api-addr", "", "Override kubeconfig and communicate directly with the control plane at host:port (mostly for testing)") vizCmd.PersistentFlags().StringVar(&vizNamespace, "viz-namespace", "", "Name of the linkerd-viz namespace. If not set, it's automatically detected") vizCmd.PersistentFlags().BoolVar(&verbose, "verbose", false, "Turn on debug logging") vizCmd.AddCommand(NewCmdAuthz()) vizCmd.AddCommand(NewCmdCheck()) vizCmd.AddCommand(NewCmdDashboard()) vizCmd.AddCommand(NewCmdEdges()) vizCmd.AddCommand(newCmdInstall()) vizCmd.AddCommand(newCmdList()) vizCmd.AddCommand(newCmdProfile()) vizCmd.AddCommand(NewCmdRoutes()) vizCmd.AddCommand(NewCmdStat()) vizCmd.AddCommand(NewCmdTap()) vizCmd.AddCommand(NewCmdTop()) vizCmd.AddCommand(newCmdUninstall()) vizCmd.AddCommand(newCmdAllowScrapes()) vizCmd.AddCommand(newCmdPrune()) // resource-aware completion flag configurations pkgcmd.ConfigureNamespaceFlagCompletion( vizCmd, []string{"linkerd-namespace"}, kubeconfigPath, impersonate, impersonateGroup, kubeContext) pkgcmd.ConfigureKubeContextFlagCompletion(vizCmd, kubeconfigPath) return vizCmd }