...

Source file src/github.com/linkerd/linkerd2/viz/cmd/check.go

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

     1  package cmd
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"os"
     7  	"time"
     8  
     9  	pkgcmd "github.com/linkerd/linkerd2/pkg/cmd"
    10  	"github.com/linkerd/linkerd2/pkg/healthcheck"
    11  	vizHealthCheck "github.com/linkerd/linkerd2/viz/pkg/healthcheck"
    12  	"github.com/spf13/cobra"
    13  )
    14  
    15  type checkOptions struct {
    16  	proxy     bool
    17  	wait      time.Duration
    18  	namespace string
    19  	output    string
    20  }
    21  
    22  func newCheckOptions() *checkOptions {
    23  	return &checkOptions{
    24  		wait:   300 * time.Second,
    25  		output: healthcheck.TableOutput,
    26  	}
    27  }
    28  
    29  func (options *checkOptions) validate() error {
    30  	if options.output != healthcheck.TableOutput && options.output != healthcheck.JSONOutput && options.output != healthcheck.ShortOutput {
    31  		return fmt.Errorf("Invalid output type '%s'. Supported output types are: %s, %s, %s", options.output, healthcheck.JSONOutput, healthcheck.TableOutput, healthcheck.ShortOutput)
    32  	}
    33  	return nil
    34  }
    35  
    36  // NewCmdCheck generates a new cobra command for the viz extension.
    37  func NewCmdCheck() *cobra.Command {
    38  	options := newCheckOptions()
    39  	cmd := &cobra.Command{
    40  		Use:   "check [flags]",
    41  		Args:  cobra.NoArgs,
    42  		Short: "Check the Linkerd Viz extension for potential problems",
    43  		Long: `Check the Linkerd Viz extension for potential problems.
    44  
    45  The check command will perform a series of checks to validate that the Linkerd Viz
    46  extension is configured correctly. If the command encounters a failure it will
    47  print additional information about the failure and exit with a non-zero exit
    48  code.`,
    49  		Example: `  # Check that the viz extension is up and running
    50    linkerd viz check`,
    51  		RunE: func(cmd *cobra.Command, args []string) error {
    52  
    53  			return configureAndRunChecks(stdout, stderr, options)
    54  		},
    55  	}
    56  
    57  	cmd.Flags().StringVarP(&options.output, "output", "o", options.output, "Output format. One of: table, json, short")
    58  	cmd.Flags().BoolVar(&options.proxy, "proxy", options.proxy, "Also run data-plane checks, to determine if the data plane is healthy")
    59  	cmd.Flags().DurationVar(&options.wait, "wait", options.wait, "Maximum allowed time for all tests to pass")
    60  	cmd.Flags().StringVarP(&options.namespace, "namespace", "n", options.namespace, "Namespace to use for --proxy checks (default: all namespaces)")
    61  
    62  	pkgcmd.ConfigureNamespaceFlagCompletion(
    63  		cmd, []string{"namespace"},
    64  		kubeconfigPath, impersonate, impersonateGroup, kubeContext)
    65  	return cmd
    66  }
    67  
    68  func configureAndRunChecks(wout io.Writer, werr io.Writer, options *checkOptions) error {
    69  	err := options.validate()
    70  	if err != nil {
    71  		return fmt.Errorf("validation error when executing check command: %w", err)
    72  	}
    73  
    74  	hc := vizHealthCheck.NewHealthChecker([]healthcheck.CategoryID{}, &vizHealthCheck.VizOptions{
    75  		Options: &healthcheck.Options{
    76  			ControlPlaneNamespace: controlPlaneNamespace,
    77  			KubeConfig:            kubeconfigPath,
    78  			KubeContext:           kubeContext,
    79  			Impersonate:           impersonate,
    80  			ImpersonateGroup:      impersonateGroup,
    81  			APIAddr:               apiAddr,
    82  			RetryDeadline:         time.Now().Add(options.wait),
    83  			DataPlaneNamespace:    options.namespace,
    84  		},
    85  		VizNamespaceOverride: vizNamespace,
    86  	})
    87  	err = hc.InitializeKubeAPIClient()
    88  	if err != nil {
    89  		fmt.Fprintf(werr, "Error initializing k8s API client: %s\n", err)
    90  		os.Exit(1)
    91  	}
    92  
    93  	hc.AppendCategories(hc.VizCategory(true))
    94  	if options.proxy {
    95  		hc.AppendCategories(hc.VizDataPlaneCategory())
    96  	}
    97  	success, warning := healthcheck.RunChecks(wout, werr, hc, options.output)
    98  	healthcheck.PrintChecksResult(wout, options.output, success, warning)
    99  
   100  	if !success {
   101  		os.Exit(1)
   102  	}
   103  
   104  	return nil
   105  }
   106  

View as plain text