github.com/argoproj/argo-cd/v3@v3.2.1/cmd/argocd/commands/admin/dashboard.go (about)

     1  package admin
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"os/signal"
     7  	"syscall"
     8  
     9  	"github.com/spf13/cobra"
    10  	"k8s.io/client-go/tools/clientcmd"
    11  
    12  	"github.com/argoproj/argo-cd/v3/util/cli"
    13  
    14  	"github.com/argoproj/argo-cd/v3/cmd/argocd/commands/headless"
    15  	"github.com/argoproj/argo-cd/v3/cmd/argocd/commands/initialize"
    16  	"github.com/argoproj/argo-cd/v3/common"
    17  	argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient"
    18  	"github.com/argoproj/argo-cd/v3/util/errors"
    19  )
    20  
    21  // DashboardConfig holds the configuration for starting the dashboard
    22  type DashboardConfig struct {
    23  	Port         int
    24  	Address      string
    25  	ClientOpts   *argocdclient.ClientOptions
    26  	ClientConfig clientcmd.ClientConfig
    27  	Context      string
    28  }
    29  
    30  type dashboard struct {
    31  	startLocalServer func(ctx context.Context, clientOpts *argocdclient.ClientOptions, contextName string, port *int, address *string, clientConfig clientcmd.ClientConfig) (func(), error)
    32  }
    33  
    34  // NewDashboard initializes a new dashboard with default dependencies
    35  func NewDashboard() *dashboard {
    36  	return &dashboard{
    37  		startLocalServer: headless.MaybeStartLocalServer,
    38  	}
    39  }
    40  
    41  // Run runs the dashboard and blocks until context is done
    42  func (ds *dashboard) Run(ctx context.Context, config *DashboardConfig) error {
    43  	ctx, stop := signal.NotifyContext(ctx, syscall.SIGINT, syscall.SIGTERM)
    44  	defer stop()
    45  	config.ClientOpts.Core = true
    46  	println("starting dashboard")
    47  	shutDownFunc, err := ds.startLocalServer(ctx, config.ClientOpts, config.Context, &config.Port, &config.Address, config.ClientConfig)
    48  	if err != nil {
    49  		return fmt.Errorf("could not start dashboard: %w", err)
    50  	}
    51  	fmt.Printf("Argo CD UI is available at http://%s:%d\n", config.Address, config.Port)
    52  	<-ctx.Done()
    53  	stop() // unregister the signal handler as soon as we receive a signal
    54  	println("signal received, shutting down dashboard")
    55  	if shutDownFunc != nil {
    56  		shutDownFunc()
    57  	}
    58  	println("clean shutdown")
    59  	return nil
    60  }
    61  
    62  func NewDashboardCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
    63  	config := &DashboardConfig{ClientOpts: clientOpts}
    64  	cmd := &cobra.Command{
    65  		Use:   "dashboard",
    66  		Short: "Starts Argo CD Web UI locally",
    67  		Run: func(cmd *cobra.Command, _ []string) {
    68  			config.Context = initialize.RetrieveContextIfChanged(cmd.Flag("context"))
    69  			errors.CheckError(NewDashboard().Run(cmd.Context(), config))
    70  		},
    71  		Example: `# Start the Argo CD Web UI locally on the default port and address
    72  $ argocd admin dashboard
    73  
    74  # Start the Argo CD Web UI locally on a custom port and address
    75  $ argocd admin dashboard --port 8080 --address 127.0.0.1
    76  
    77  # Start the Argo CD Web UI with GZip compression
    78  $ argocd admin dashboard --redis-compress gzip
    79    `,
    80  	}
    81  	config.ClientConfig = cli.AddKubectlFlagsToSet(cmd.Flags())
    82  	cmd.Flags().IntVar(&config.Port, "port", common.DefaultPortAPIServer, "Listen on given port")
    83  	cmd.Flags().StringVar(&config.Address, "address", common.DefaultAddressAdminDashboard, "Listen on given address")
    84  	return cmd
    85  }