github.com/olli-ai/jx/v2@v2.0.400-0.20210921045218-14731b4dd448/pkg/cmd/step/step_wait_for_chart.go (about)

     1  package step
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  	"time"
     8  
     9  	"github.com/pkg/errors"
    10  
    11  	"github.com/olli-ai/jx/v2/pkg/cmd/opts/step"
    12  
    13  	"github.com/olli-ai/jx/v2/pkg/cmd/helper"
    14  
    15  	"github.com/jenkins-x/jx-logging/pkg/log"
    16  	"github.com/olli-ai/jx/v2/pkg/cmd/opts"
    17  	"github.com/olli-ai/jx/v2/pkg/cmd/templates"
    18  	"github.com/olli-ai/jx/v2/pkg/util"
    19  	"github.com/spf13/cobra"
    20  )
    21  
    22  const (
    23  	optionChartName    = "chart-name"
    24  	optionChartVersion = "chart-version"
    25  	optionChartRepo    = "chart-repo"
    26  	optionRepoUsername = "repo-username"
    27  	optionRepoPassword = "repo-password" // pragma: allowlist secret
    28  )
    29  
    30  // WaitForChartOptions contains the command line flags
    31  type WaitForChartOptions struct {
    32  	*step.StepOptions
    33  
    34  	ChartName    string
    35  	ChartVersion string
    36  	ChartRepo    string
    37  	RepoUsername string
    38  	RepoPassword string
    39  	Timeout      string
    40  	PollTime     string
    41  
    42  	// calculated fields
    43  	TimeoutDuration time.Duration
    44  	PollDuration    time.Duration
    45  }
    46  
    47  var (
    48  	// StepWaitForChartLong CLI long description
    49  	StepWaitForChartLong = templates.LongDesc(`
    50  		Waits for the given Chart to be available in a Helm repository
    51  
    52  `)
    53  	// StepWaitForChartExample CLI example
    54  	StepWaitForChartExample = templates.Examples(`
    55  		# wait for a chart to be available
    56  		jx step wait-for-chart --chart-name foo --chart-version 1.0.0
    57  
    58  `)
    59  )
    60  
    61  // NewCmdStepWaitForChart creates the CLI command
    62  func NewCmdStepWaitForChart(commonOpts *opts.CommonOptions) *cobra.Command {
    63  	options := WaitForChartOptions{
    64  		StepOptions: &step.StepOptions{
    65  			CommonOptions: commonOpts,
    66  		},
    67  	}
    68  	cmd := &cobra.Command{
    69  		Use:     "wait-for-chart",
    70  		Short:   "Waits for the given chart to be available in a helm repository",
    71  		Long:    StepWaitForChartLong,
    72  		Example: StepWaitForChartExample,
    73  		Run: func(cmd *cobra.Command, args []string) {
    74  			options.Cmd = cmd
    75  			options.Args = args
    76  			err := options.Run()
    77  			helper.CheckErr(err)
    78  		},
    79  	}
    80  	cmd.Flags().StringVarP(&options.ChartName, optionChartName, "", "", "Helm chart name to search for [required]")
    81  	cmd.Flags().StringVarP(&options.ChartVersion, optionChartVersion, "", "", "Helm chart version to search for [required]")
    82  	cmd.Flags().StringVarP(&options.ChartRepo, optionChartRepo, "", "https://storage.googleapis.com/chartmuseum.jenkins-x.io", "The repo to search for the helm chart")
    83  	cmd.Flags().StringVarP(&options.RepoUsername, optionRepoUsername, "", "", "Helm Repo username if auth enabled")
    84  	cmd.Flags().StringVarP(&options.RepoPassword, optionRepoPassword, "", "", "Helm Repo password if auth enabled")
    85  	cmd.Flags().StringVarP(&options.Timeout, opts.OptionTimeout, "t", "1h", "The duration before we consider this operation failed")
    86  	cmd.Flags().StringVarP(&options.PollTime, optionPollTime, "", "30s", "The amount of time between polls for the Chart being present")
    87  	return cmd
    88  }
    89  
    90  // Run runs the command
    91  func (o *WaitForChartOptions) Run() error {
    92  	var err error
    93  	if o.PollTime != "" {
    94  		o.PollDuration, err = time.ParseDuration(o.PollTime)
    95  		if err != nil {
    96  			return fmt.Errorf("Invalid duration format %s for option --%s: %s", o.PollTime, optionPollTime, err)
    97  		}
    98  	}
    99  	if o.Timeout != "" {
   100  		o.TimeoutDuration, err = time.ParseDuration(o.Timeout)
   101  		if err != nil {
   102  			return fmt.Errorf("Invalid duration format %s for option --%s: %s", o.Timeout, opts.OptionTimeout, err)
   103  		}
   104  	}
   105  
   106  	if o.ChartName == "" {
   107  		return util.MissingOption(optionChartName)
   108  	}
   109  	if o.ChartVersion == "" {
   110  		return util.MissingOption(optionChartVersion)
   111  	}
   112  	log.Logger().Infof("Waiting for chart %s version %s at %s", util.ColorInfo(o.ChartName), util.ColorInfo(o.ChartVersion), util.ColorInfo(o.ChartRepo))
   113  
   114  	dir, err := ioutil.TempDir("", "wait_for_chart")
   115  	if err != nil {
   116  		return errors.Wrap(err, "creating temporary directory")
   117  	}
   118  	defer os.RemoveAll(dir) // clean up
   119  
   120  	fn := func() error {
   121  		return o.Helm().FetchChart(o.ChartName, o.ChartVersion, true, dir, o.ChartRepo, o.RepoUsername, o.RepoPassword)
   122  	}
   123  
   124  	err = o.RetryQuietlyUntilTimeout(o.TimeoutDuration, o.PollDuration, fn)
   125  	if err == nil {
   126  		log.Logger().Infof("Found chart name %s version %s at %s", util.ColorInfo(o.ChartName), util.ColorInfo(o.ChartVersion), util.ColorInfo(o.ChartRepo))
   127  		return nil
   128  	}
   129  	log.Logger().Warnf("Failed to find chart %s version  %s at %s due to %s", o.ChartName, o.ChartVersion, o.ChartRepo, err)
   130  	return err
   131  }