github.com/telepresenceio/telepresence/v2@v2.20.0-pro.6.0.20240517030216-236ea954e789/pkg/client/cli/cmd/helm.go (about)

     1  package cmd
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/spf13/cobra"
     7  	"github.com/spf13/pflag"
     8  
     9  	"github.com/telepresenceio/telepresence/v2/pkg/client/cli/daemon"
    10  	"github.com/telepresenceio/telepresence/v2/pkg/client/cli/helm"
    11  	"github.com/telepresenceio/telepresence/v2/pkg/client/scout"
    12  )
    13  
    14  func helmCmd() *cobra.Command {
    15  	cmd := &cobra.Command{
    16  		Use: "helm",
    17  	}
    18  	cmd.AddCommand(helmInstall(), helmUpgrade(), helmUninstall())
    19  	return cmd
    20  }
    21  
    22  type HelmCommand struct {
    23  	helm.Request
    24  	AllValues map[string]any
    25  	rq        *daemon.CobraRequest
    26  }
    27  
    28  var (
    29  	HelmInstallExtendFlagsFunc func(*pflag.FlagSet)                                      //nolint:gochecknoglobals // extension point
    30  	HelmExtendFlagsFunc        func(*pflag.FlagSet)                                      //nolint:gochecknoglobals // extension point
    31  	HelmInstallPrologFunc      func(context.Context, *pflag.FlagSet, *HelmCommand) error //nolint:gochecknoglobals // extension point
    32  )
    33  
    34  func helmInstall() *cobra.Command {
    35  	var upgrade bool
    36  
    37  	ha := &HelmCommand{
    38  		Request: helm.Request{
    39  			Type: helm.Install,
    40  		},
    41  	}
    42  	cmd := &cobra.Command{
    43  		Use:   "install",
    44  		Args:  cobra.NoArgs,
    45  		Short: "Install telepresence traffic manager",
    46  		RunE: func(cmd *cobra.Command, args []string) error {
    47  			if upgrade {
    48  				ha.Request.Type = helm.Upgrade
    49  			}
    50  			return ha.run(cmd, args)
    51  		},
    52  	}
    53  
    54  	flags := cmd.Flags()
    55  	flags.BoolVarP(&ha.NoHooks, "no-hooks", "", false, "prevent hooks from running during install")
    56  	flags.BoolVarP(&upgrade, "upgrade", "u", false, "replace the traffic manager if it already exists")
    57  	ha.addValueSettingFlags(flags)
    58  	ha.addCRDsFlags(flags)
    59  	uf := flags.Lookup("upgrade")
    60  	uf.Hidden = true
    61  	uf.Deprecated = `Use "telepresence helm upgrade" instead of "telepresence helm install --upgrade"`
    62  	ha.rq = daemon.InitRequest(cmd)
    63  	return cmd
    64  }
    65  
    66  func helmUpgrade() *cobra.Command {
    67  	ha := &HelmCommand{
    68  		Request: helm.Request{
    69  			Type: helm.Upgrade,
    70  		},
    71  	}
    72  	cmd := &cobra.Command{
    73  		Use:   "upgrade",
    74  		Args:  cobra.NoArgs,
    75  		Short: "Upgrade telepresence traffic manager",
    76  		RunE:  ha.run,
    77  	}
    78  
    79  	flags := cmd.Flags()
    80  	ha.addValueSettingFlags(flags)
    81  	ha.addCRDsFlags(flags)
    82  	flags.BoolVarP(&ha.NoHooks, "no-hooks", "", false, "disable pre/post upgrade hooks")
    83  	flags.BoolVarP(&ha.ResetValues, "reset-values", "", false, "when upgrading, reset the values to the ones built into the chart")
    84  	flags.BoolVarP(&ha.ReuseValues, "reuse-values", "", false,
    85  		"when upgrading, reuse the last release's values and merge in any overrides from the command line via --set and -f")
    86  	ha.rq = daemon.InitRequest(cmd)
    87  	return cmd
    88  }
    89  
    90  func (ha *HelmCommand) addValueSettingFlags(flags *pflag.FlagSet) {
    91  	flags.StringArrayVarP(&ha.ValueFiles, "values", "f", []string{},
    92  		"specify values in a YAML file or a URL (can specify multiple)")
    93  	flags.StringArrayVarP(&ha.Values, "set", "", []string{},
    94  		"specify a value as a.b=v (can specify multiple or separate values with commas: a.b=v1,a.c=v2)")
    95  	flags.StringArrayVarP(&ha.FileValues, "set-file", "", []string{},
    96  		"set values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)")
    97  	flags.StringArrayVarP(&ha.JSONValues, "set-json", "", []string{},
    98  		"set JSON values on the command line (can specify multiple or separate values with commas: a.b=jsonval1,a.c=jsonval2)")
    99  	flags.StringArrayVarP(&ha.StringValues, "set-string", "", []string{},
   100  		"set STRING values on the command line (can specify multiple or separate values with commas: a.b=val1,a.c=val2)")
   101  	if HelmInstallExtendFlagsFunc != nil {
   102  		HelmInstallExtendFlagsFunc(flags)
   103  	}
   104  }
   105  
   106  func (ha *HelmCommand) addCRDsFlags(flags *pflag.FlagSet) {
   107  	if HelmExtendFlagsFunc != nil {
   108  		HelmExtendFlagsFunc(flags)
   109  	}
   110  }
   111  
   112  func helmUninstall() *cobra.Command {
   113  	ha := &HelmCommand{
   114  		Request: helm.Request{
   115  			Type: helm.Uninstall,
   116  		},
   117  	}
   118  	cmd := &cobra.Command{
   119  		Use:   "uninstall",
   120  		Args:  cobra.NoArgs,
   121  		Short: "Uninstall telepresence traffic manager",
   122  		RunE:  ha.run,
   123  	}
   124  	flags := cmd.Flags()
   125  	flags.BoolVarP(&ha.NoHooks, "no-hooks", "", false, "prevent hooks from running during uninstallation")
   126  	ha.addCRDsFlags(flags)
   127  	ha.rq = daemon.InitRequest(cmd)
   128  	return cmd
   129  }
   130  
   131  func (ha *HelmCommand) Type() helm.RequestType {
   132  	return ha.Request.Type
   133  }
   134  
   135  func (ha *HelmCommand) run(cmd *cobra.Command, _ []string) (err error) {
   136  	if err = ha.rq.CommitFlags(cmd); err != nil {
   137  		return err
   138  	}
   139  	ctx := cmd.Context()
   140  	ctx = scout.NewReporter(ctx, "cli")
   141  	defer func() {
   142  		if err == nil {
   143  			if ha.Type() == helm.Uninstall {
   144  				scout.Report(ctx, "helm_uninstall_success")
   145  			} else {
   146  				scout.Report(ctx, "helm_install_success", scout.Entry{Key: "upgrade", Value: ha.Type() == helm.Upgrade})
   147  			}
   148  		} else {
   149  			if ha.Type() == helm.Uninstall {
   150  				scout.Report(ctx, "helm_uninstall_failure", scout.Entry{Key: "error", Value: err.Error()})
   151  			} else {
   152  				scout.Report(ctx, "helm_install_failure", scout.Entry{Key: "error", Value: err.Error()}, scout.Entry{Key: "upgrade", Value: ha.Type() == helm.Upgrade})
   153  			}
   154  		}
   155  	}()
   156  
   157  	if HelmInstallPrologFunc != nil {
   158  		if err = HelmInstallPrologFunc(ctx, cmd.Flags(), ha); err != nil {
   159  			return err
   160  		}
   161  	}
   162  	return ha.Run(ctx, &ha.rq.Request.ConnectRequest)
   163  }