...

Source file src/github.com/linkerd/linkerd2/cli/cmd/root.go

Documentation: github.com/linkerd/linkerd2/cli/cmd

     1  package cmd
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"regexp"
     7  	"strings"
     8  
     9  	"github.com/fatih/color"
    10  	"github.com/linkerd/linkerd2/cli/flag"
    11  	jaeger "github.com/linkerd/linkerd2/jaeger/cmd"
    12  	multicluster "github.com/linkerd/linkerd2/multicluster/cmd"
    13  	pkgcmd "github.com/linkerd/linkerd2/pkg/cmd"
    14  	"github.com/linkerd/linkerd2/pkg/flags"
    15  	"github.com/linkerd/linkerd2/pkg/healthcheck"
    16  	viz "github.com/linkerd/linkerd2/viz/cmd"
    17  	log "github.com/sirupsen/logrus"
    18  	"github.com/spf13/cobra"
    19  )
    20  
    21  const (
    22  	defaultLinkerdNamespace = "linkerd"
    23  	defaultCNINamespace     = "linkerd-cni"
    24  	defaultClusterDomain    = "cluster.local"
    25  
    26  	jsonOutput  = healthcheck.JSONOutput
    27  	tableOutput = healthcheck.TableOutput
    28  	shortOutput = healthcheck.ShortOutput
    29  )
    30  
    31  var (
    32  	// special handling for Windows, on all other platforms these resolve to
    33  	// os.Stdout and os.Stderr, thanks to https://github.com/mattn/go-colorable
    34  	stdout = color.Output
    35  	stderr = color.Error
    36  
    37  	okStatus   = color.New(color.FgGreen, color.Bold).SprintFunc()("\u221A")  // √
    38  	warnStatus = color.New(color.FgYellow, color.Bold).SprintFunc()("\u203C") // ‼
    39  	failStatus = color.New(color.FgRed, color.Bold).SprintFunc()("\u00D7")    // ×
    40  
    41  	controlPlaneNamespace string
    42  	cniNamespace          string
    43  	apiAddr               string // An empty value means "use the Kubernetes configuration"
    44  	kubeconfigPath        string
    45  	kubeContext           string
    46  	impersonate           string
    47  	impersonateGroup      []string
    48  	verbose               bool
    49  
    50  	// These regexs are not as strict as they could be, but are a quick and dirty
    51  	// sanity check against illegal characters.
    52  	alphaNumDash              = regexp.MustCompile(`^[a-zA-Z0-9-]+$`)
    53  	alphaNumDashDot           = regexp.MustCompile(`^[\.a-zA-Z0-9-]+$`)
    54  	alphaNumDashDotSlashColon = regexp.MustCompile(`^[\./a-zA-Z0-9-:]+$`)
    55  
    56  	// Full Rust log level syntax at
    57  	// https://docs.rs/env_logger/0.6.0/env_logger/#enabling-logging
    58  	r                  = strings.NewReplacer("\t", "", "\n", "")
    59  	validProxyLogLevel = regexp.MustCompile(r.Replace(`
    60  		^(
    61  			(
    62  				(trace|debug|warn|info|error)|
    63  				(\w|::)+|
    64  				((\w|::)+=(trace|debug|warn|info|error))
    65  			)(?:,|$)
    66  		)+$`))
    67  )
    68  
    69  // RootCmd represents the root Cobra command
    70  var RootCmd = &cobra.Command{
    71  	Use:   "linkerd",
    72  	Short: "linkerd manages the Linkerd service mesh",
    73  	Long:  `linkerd manages the Linkerd service mesh.`,
    74  	PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
    75  		// enable / disable logging
    76  		if verbose {
    77  			log.SetLevel(log.DebugLevel)
    78  		} else {
    79  			log.SetLevel(log.PanicLevel)
    80  		}
    81  
    82  		controlPlaneNamespaceFromEnv := os.Getenv(flags.EnvOverrideNamespace)
    83  		if controlPlaneNamespace == defaultLinkerdNamespace && controlPlaneNamespaceFromEnv != "" {
    84  			controlPlaneNamespace = controlPlaneNamespaceFromEnv
    85  		}
    86  
    87  		if !alphaNumDash.MatchString(controlPlaneNamespace) {
    88  			return fmt.Errorf("%s is not a valid namespace", controlPlaneNamespace)
    89  		}
    90  
    91  		return nil
    92  	},
    93  }
    94  
    95  func init() {
    96  	RootCmd.PersistentFlags().StringVarP(&controlPlaneNamespace, "linkerd-namespace", "L",
    97  		defaultLinkerdNamespace,
    98  		fmt.Sprintf("Namespace in which Linkerd is installed ($%s)", flags.EnvOverrideNamespace))
    99  	RootCmd.PersistentFlags().StringVarP(&cniNamespace, "cni-namespace", "", defaultCNINamespace, "Namespace in which the Linkerd CNI plugin is installed")
   100  	RootCmd.PersistentFlags().StringVar(&kubeconfigPath, "kubeconfig", "", "Path to the kubeconfig file to use for CLI requests")
   101  	RootCmd.PersistentFlags().StringVar(&kubeContext, "context", "", "Name of the kubeconfig context to use")
   102  	RootCmd.PersistentFlags().StringVar(&impersonate, "as", "", "Username to impersonate for Kubernetes operations")
   103  	RootCmd.PersistentFlags().StringArrayVar(&impersonateGroup, "as-group", []string{}, "Group to impersonate for Kubernetes operations")
   104  	RootCmd.PersistentFlags().StringVar(&apiAddr, "api-addr", "", "Override kubeconfig and communicate directly with the control plane at host:port (mostly for testing)")
   105  	RootCmd.PersistentFlags().BoolVar(&verbose, "verbose", false, "Turn on debug logging")
   106  	RootCmd.AddCommand(newCmdAlpha())
   107  	RootCmd.AddCommand(newCmdCheck())
   108  	RootCmd.AddCommand(newCmdCompletion())
   109  	RootCmd.AddCommand(newCmdDiagnostics())
   110  	RootCmd.AddCommand(newCmdDoc())
   111  	RootCmd.AddCommand(newCmdIdentity())
   112  	RootCmd.AddCommand(newCmdInject())
   113  	RootCmd.AddCommand(newCmdInstall())
   114  	RootCmd.AddCommand(newCmdInstallCNIPlugin())
   115  	RootCmd.AddCommand(newCmdProfile())
   116  	RootCmd.AddCommand(newCmdAuthz())
   117  	RootCmd.AddCommand(newCmdUninject())
   118  	RootCmd.AddCommand(newCmdUpgrade())
   119  	RootCmd.AddCommand(newCmdVersion())
   120  	RootCmd.AddCommand(newCmdUninstall())
   121  	RootCmd.AddCommand(newCmdPrune())
   122  
   123  	// Extension Sub Commands
   124  	RootCmd.AddCommand(jaeger.NewCmdJaeger())
   125  	RootCmd.AddCommand(multicluster.NewCmdMulticluster())
   126  	RootCmd.AddCommand(viz.NewCmdViz())
   127  
   128  	// Viz Extension sub commands
   129  	RootCmd.AddCommand(deprecateCmd(viz.NewCmdDashboard()))
   130  	RootCmd.AddCommand(deprecateCmd(viz.NewCmdEdges()))
   131  	RootCmd.AddCommand(deprecateCmd(viz.NewCmdRoutes()))
   132  	RootCmd.AddCommand(deprecateCmd(viz.NewCmdStat()))
   133  	RootCmd.AddCommand(deprecateCmd(viz.NewCmdTap()))
   134  	RootCmd.AddCommand(deprecateCmd(viz.NewCmdTop()))
   135  
   136  	// resource-aware completion flag configurations
   137  	pkgcmd.ConfigureNamespaceFlagCompletion(
   138  		RootCmd, []string{"linkerd-namespace", "cni-namespace"},
   139  		kubeconfigPath, impersonate, impersonateGroup, kubeContext)
   140  
   141  	pkgcmd.ConfigureKubeContextFlagCompletion(RootCmd, kubeconfigPath)
   142  }
   143  
   144  func deprecateCmd(cmd *cobra.Command) *cobra.Command {
   145  	cmd.Deprecated = fmt.Sprintf("use instead 'linkerd viz %s'\n", cmd.Use)
   146  	return cmd
   147  }
   148  
   149  func flattenFlags(flags ...[]flag.Flag) []flag.Flag {
   150  	out := []flag.Flag{}
   151  	for _, f := range flags {
   152  		out = append(out, f...)
   153  	}
   154  	return out
   155  }
   156  

View as plain text