...

Source file src/github.com/linkerd/linkerd2/jaeger/cmd/dashboard.go

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

     1  package cmd
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"os/signal"
     7  	"time"
     8  
     9  	"github.com/linkerd/linkerd2/pkg/healthcheck"
    10  	"github.com/linkerd/linkerd2/pkg/k8s"
    11  	"github.com/pkg/browser"
    12  	"github.com/spf13/cobra"
    13  )
    14  
    15  const (
    16  
    17  	// jaegerDeployment is the name of the jaeger deployment
    18  	jaegerDeployment = "jaeger"
    19  
    20  	// webPort is the http port of the jaeger deployment
    21  	webPort = 16686
    22  
    23  	// defaultHost is the default host used for port-forwarding via `jaeger dashboard`
    24  	defaultHost = "localhost"
    25  
    26  	// defaultPort is for port-forwarding via `jaeger dashboard`
    27  	defaultPort = 16686
    28  )
    29  
    30  // dashboardOptions holds values for command line flags that apply to the dashboard
    31  // command.
    32  type dashboardOptions struct {
    33  	host    string
    34  	port    int
    35  	showURL bool
    36  	wait    time.Duration
    37  }
    38  
    39  // newDashboardOptions initializes dashboard options with default
    40  // values for host, port. Also, set max wait time duration for
    41  // 300 seconds for the dashboard to become available
    42  //
    43  // These options may be overridden on the CLI at run-time
    44  func newDashboardOptions() *dashboardOptions {
    45  	return &dashboardOptions{
    46  		host: defaultHost,
    47  		port: defaultPort,
    48  		wait: 300 * time.Second,
    49  	}
    50  }
    51  
    52  // newCmdDashboard creates a new cobra command `dashboard` which contains commands for visualizing jaeger extension's dashboards.
    53  // After validating flag values, it will use the Kubernetes API to portforward requests to the Jaeger deployment
    54  // until the process gets killed/canceled
    55  func newCmdDashboard() *cobra.Command {
    56  	options := newDashboardOptions()
    57  
    58  	cmd := &cobra.Command{
    59  		Use:   "dashboard [flags]",
    60  		Short: "Open the Jaeger extension dashboard in a web browser",
    61  		Args:  cobra.NoArgs,
    62  		RunE: func(cmd *cobra.Command, args []string) error {
    63  			if options.port < 0 {
    64  				return fmt.Errorf("port must be greater than or equal to zero, was %d", options.port)
    65  			}
    66  
    67  			checkForJaeger(healthcheck.Options{
    68  				ControlPlaneNamespace: controlPlaneNamespace,
    69  				KubeConfig:            kubeconfigPath,
    70  				Impersonate:           impersonate,
    71  				ImpersonateGroup:      impersonateGroup,
    72  				KubeContext:           kubeContext,
    73  				APIAddr:               apiAddr,
    74  				RetryDeadline:         time.Now().Add(options.wait),
    75  			})
    76  
    77  			k8sAPI, err := k8s.NewAPI(kubeconfigPath, kubeContext, impersonate, impersonateGroup, 0)
    78  			if err != nil {
    79  				return err
    80  			}
    81  
    82  			jaegerNamespace, err := k8sAPI.GetNamespaceWithExtensionLabel(cmd.Context(), JaegerExtensionName)
    83  			if err != nil {
    84  				return err
    85  			}
    86  
    87  			signals := make(chan os.Signal, 1)
    88  			signal.Notify(signals, os.Interrupt)
    89  			defer signal.Stop(signals)
    90  
    91  			portforward, err := k8s.NewPortForward(
    92  				cmd.Context(),
    93  				k8sAPI,
    94  				jaegerNamespace.Name,
    95  				jaegerDeployment,
    96  				options.host,
    97  				options.port,
    98  				webPort,
    99  				verbose,
   100  			)
   101  			if err != nil {
   102  				fmt.Fprintf(os.Stderr, "Failed to initialize port-forward: %s\n", err)
   103  				os.Exit(1)
   104  			}
   105  
   106  			if err = portforward.Init(); err != nil {
   107  				// TODO: consider falling back to an ephemeral port if defaultPort is taken
   108  				fmt.Fprintf(os.Stderr, "Error running port-forward: %s\nCheck for `jaeger dashboard` running in other terminal sessions, or use the `--port` flag.\n", err)
   109  				os.Exit(1)
   110  			}
   111  
   112  			go func() {
   113  				<-signals
   114  				portforward.Stop()
   115  			}()
   116  
   117  			webURL := portforward.URLFor("")
   118  
   119  			fmt.Printf("Jaeger extension dashboard available at:\n%s\n", webURL)
   120  
   121  			if !options.showURL {
   122  				err = browser.OpenURL(webURL)
   123  				if err != nil {
   124  					fmt.Fprintln(os.Stderr, "Failed to open dashboard automatically")
   125  					fmt.Fprintf(os.Stderr, "Visit %s in your browser to view the dashboard\n", webURL)
   126  				}
   127  			}
   128  
   129  			<-portforward.GetStop()
   130  			return nil
   131  		},
   132  	}
   133  
   134  	// This is identical to what `kubectl proxy --help` reports, `--port 0` indicates a random port.
   135  	cmd.PersistentFlags().StringVar(&options.host, "address", options.host, "The address at which to serve requests")
   136  	cmd.PersistentFlags().IntVarP(&options.port, "port", "p", options.port, "The local port on which to serve requests (when set to 0, a random port will be used)")
   137  	cmd.PersistentFlags().BoolVar(&options.showURL, "show-url", options.showURL, "show only URL in the CLI, and do not open the browser")
   138  	cmd.PersistentFlags().DurationVar(&options.wait, "wait", options.wait, "Wait for dashboard to become available if it's not available when the command is run")
   139  
   140  	return cmd
   141  }
   142  

View as plain text