github.com/codefresh-io/kcfi@v0.0.0-20230301195427-c1578715cc46/cmd/kcfi/cf_embeded_chart.go (about)

     1  /*
     2  Copyright The Codefresh Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package main
    18  
    19  import (
    20  	"fmt"
    21  	"io"
    22  	"time"
    23  
    24  	"github.com/pkg/errors"
    25  	"github.com/spf13/cobra"
    26  
    27  	"github.com/codefresh-io/kcfi/pkg/helm-internal/completion"
    28  	"helm.sh/helm/v3/cmd/helm/require"
    29  	"helm.sh/helm/v3/pkg/action"
    30  
    31  	"helm.sh/helm/v3/pkg/cli/output"
    32  	"helm.sh/helm/v3/pkg/cli/values"
    33  	//"helm.sh/helm/v3/pkg/downloader"
    34  	"helm.sh/helm/v3/pkg/getter"
    35  	"helm.sh/helm/v3/pkg/release"
    36  	"helm.sh/helm/v3/pkg/storage/driver"
    37  
    38  	"github.com/codefresh-io/kcfi/pkg/charts"
    39  )
    40  
    41  const embededChartDeployDesc = `
    42  This command deploys embeded chart
    43  Accepts parameters of helm upgrade: 
    44  kcfi <chart-name> deploy [-f <values-file>] [--set key=value] [--set-file key=/path/to/file] [--atomic]
    45  `
    46  
    47  func embededChartRunInstall(releaseName string, embededChart string, args []string, client *action.Install, valueOpts *values.Options, out io.Writer) (*release.Release, error) {
    48  	debug("Original chart version: %q", client.Version)
    49  	if client.Version == "" && client.Devel {
    50  		debug("setting version to >0.0.0-0")
    51  		client.Version = ">0.0.0-0"
    52  	}
    53  
    54  	p := getter.All(settings)
    55  	vals, err := valueOpts.MergeValues(p)
    56  	if err != nil {
    57  		return nil, err
    58  	}
    59  
    60  	// Check chart dependencies to make sure all are present in /charts
    61  	chartRequested, err := charts.Load(embededChart)
    62  	if err != nil {
    63  		return nil, err
    64  	}
    65  	client.ReleaseName = releaseName
    66  
    67  	validInstallableChart, err := isChartInstallable(chartRequested)
    68  	if !validInstallableChart {
    69  		return nil, err
    70  	}
    71  
    72  	if chartRequested.Metadata.Deprecated {
    73  		fmt.Fprintln(out, "WARNING: This chart is deprecated")
    74  	}
    75  
    76  	// if req := chartRequested.Metadata.Dependencies; req != nil {
    77  	// 	// If CheckDependencies returns an error, we have unfulfilled dependencies.
    78  	// 	// As of Helm 2.4.0, this is treated as a stopping condition:
    79  	// 	// https://github.com/helm/helm/issues/2209
    80  	// 	if err := action.CheckDependencies(chartRequested, req); err != nil {
    81  	// 		if client.DependencyUpdate {
    82  	// 			man := &downloader.Manager{
    83  	// 				Out:              out,
    84  	// 				ChartPath:        cp,
    85  	// 				Keyring:          client.ChartPathOptions.Keyring,
    86  	// 				SkipUpdate:       false,
    87  	// 				Getters:          p,
    88  	// 				RepositoryConfig: settings.RepositoryConfig,
    89  	// 				RepositoryCache:  settings.RepositoryCache,
    90  	// 				Debug:            settings.Debug,
    91  	// 			}
    92  	// 			if err := man.Update(); err != nil {
    93  	// 				return nil, err
    94  	// 			}
    95  	// 			// Reload the chart with the updated Chart.lock file.
    96  	// 			if chartRequested, err = loader.Load(cp); err != nil {
    97  	// 				return nil, errors.Wrap(err, "failed reloading chart after repo update")
    98  	// 			}
    99  	// 		} else {
   100  	// 			return nil, err
   101  	// 		}
   102  	// 	}
   103  	// }
   104  
   105  	client.Namespace = settings.Namespace()
   106  	return client.Run(chartRequested, vals)
   107  }
   108  
   109  func newEmbededChartUpgradeCmd(releaseName string, embededChart string, cfg *action.Configuration, out io.Writer) *cobra.Command {
   110  	client := action.NewUpgrade(cfg)
   111  	valueOpts := &values.Options{}
   112  	var outfmt output.Format
   113  	var createNamespace bool
   114  
   115  	cmd := &cobra.Command{
   116  		Use:   "deploy",
   117  		Short: "deploys embeded chart",
   118  		Long:  embededChartDeployDesc,
   119  		Args:  require.NoArgs,
   120  		//RunE: embededChartRunEFunc(releaseName, embededChart, cfg, client, valueOpts, createNamespace, outfmt, out),
   121  		RunE: func(cmd *cobra.Command, args []string) error {
   122  			// Fixes #7002 - Support reading values from STDIN for `upgrade` command
   123  			// Must load values AFTER determining if we have to call install so that values loaded from stdin are are not read twice
   124  			if client.Install {
   125  				// If a release does not exist, install it.
   126  				histClient := action.NewHistory(cfg)
   127  				histClient.Max = 1
   128  				if _, err := histClient.Run(releaseName); err == driver.ErrReleaseNotFound {
   129  					// Only print this to stdout for table output
   130  					if outfmt == output.Table {
   131  						fmt.Fprintf(out, "Release %q does not exist. Installing it now.\n", releaseName)
   132  					}
   133  					instClient := action.NewInstall(cfg)
   134  					instClient.CreateNamespace = createNamespace
   135  					instClient.ChartPathOptions = client.ChartPathOptions
   136  					instClient.DryRun = client.DryRun
   137  					instClient.DisableHooks = client.DisableHooks
   138  					instClient.SkipCRDs = client.SkipCRDs
   139  					instClient.Timeout = client.Timeout
   140  					instClient.Wait = client.Wait
   141  					instClient.Devel = client.Devel
   142  					instClient.Namespace = client.Namespace
   143  					instClient.Atomic = client.Atomic
   144  					instClient.PostRenderer = client.PostRenderer
   145  					instClient.DisableOpenAPIValidation = client.DisableOpenAPIValidation
   146  					instClient.SubNotes = client.SubNotes
   147  
   148  					rel, err := embededChartRunInstall(releaseName, embededChart, args, instClient, valueOpts, out)
   149  					if err != nil {
   150  						return err
   151  					}
   152  					return outfmt.Write(out, &statusPrinter{rel, settings.Debug})
   153  				} else if err != nil {
   154  					return err
   155  				}
   156  			}
   157  
   158  			if client.Version == "" && client.Devel {
   159  				debug("setting version to >0.0.0-0")
   160  				client.Version = ">0.0.0-0"
   161  			}
   162  
   163  			vals, err := valueOpts.MergeValues(getter.All(settings))
   164  			if err != nil {
   165  				return err
   166  			}
   167  
   168  			// Check chart dependencies to make sure all are present in /charts
   169  			ch, err := charts.Load(embededChart)
   170  			if err != nil {
   171  				return err
   172  			}
   173  
   174  			if req := ch.Metadata.Dependencies; req != nil {
   175  				if err := action.CheckDependencies(ch, req); err != nil {
   176  					return err
   177  				}
   178  			}
   179  
   180  			if ch.Metadata.Deprecated {
   181  				fmt.Fprintln(out, "WARNING: This chart is deprecated")
   182  			}
   183  
   184  			rel, err := client.Run(releaseName, ch, vals)
   185  			if err != nil {
   186  				return errors.Wrap(err, "UPGRADE FAILED")
   187  			}
   188  
   189  			if outfmt == output.Table {
   190  				fmt.Fprintf(out, "Release %q has been upgraded. Happy Helming!\n", releaseName)
   191  			}
   192  
   193  			return outfmt.Write(out, &statusPrinter{rel, settings.Debug})
   194  		},
   195  	}
   196  
   197  	// Function providing dynamic auto-completion
   198  	completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) {
   199  		if len(args) == 0 {
   200  			return compListReleases(toComplete, cfg)
   201  		}
   202  		if len(args) == 1 {
   203  			return compListCharts(toComplete, true)
   204  		}
   205  		return nil, completion.BashCompDirectiveNoFileComp
   206  	})
   207  
   208  	f := cmd.Flags()
   209  	f.BoolVar(&createNamespace, "create-namespace", false, "if --install is set, create the release namespace if not present")
   210  	f.BoolVarP(&client.Install, "install", "i", true, "if a release by this name doesn't already exist, run an install")
   211  	f.BoolVar(&client.Devel, "devel", false, "use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored")
   212  	f.BoolVar(&client.DryRun, "dry-run", false, "simulate an upgrade")
   213  	f.BoolVar(&client.Recreate, "recreate-pods", false, "performs pods restart for the resource if applicable")
   214  	f.MarkDeprecated("recreate-pods", "functionality will no longer be updated. Consult the documentation for other methods to recreate pods")
   215  	f.BoolVar(&client.Force, "force", false, "force resource updates through a replacement strategy")
   216  	f.BoolVar(&client.DisableHooks, "no-hooks", false, "disable pre/post upgrade hooks")
   217  	f.BoolVar(&client.DisableOpenAPIValidation, "disable-openapi-validation", false, "if set, the upgrade process will not validate rendered templates against the Kubernetes OpenAPI Schema")
   218  	f.BoolVar(&client.SkipCRDs, "skip-crds", false, "if set, no CRDs will be installed when an upgrade is performed with install flag enabled. By default, CRDs are installed if not already present, when an upgrade is performed with install flag enabled")
   219  	f.DurationVar(&client.Timeout, "timeout", 300*time.Second, "time to wait for any individual Kubernetes operation (like Jobs for hooks)")
   220  	f.BoolVar(&client.ResetValues, "reset-values", false, "when upgrading, reset the values to the ones built into the chart")
   221  	f.BoolVar(&client.ReuseValues, "reuse-values", false, "when upgrading, reuse the last release's values and merge in any overrides from the command line via --set and -f. If '--reset-values' is specified, this is ignored")
   222  	f.BoolVar(&client.Wait, "wait", false, "if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment, StatefulSet, or ReplicaSet are in a ready state before marking the release as successful. It will wait for as long as --timeout")
   223  	f.BoolVar(&client.Atomic, "atomic", false, "if set, upgrade process rolls back changes made in case of failed upgrade. The --wait flag will be set automatically if --atomic is used")
   224  	f.IntVar(&client.MaxHistory, "history-max", 10, "limit the maximum number of revisions saved per release. Use 0 for no limit")
   225  	f.BoolVar(&client.CleanupOnFail, "cleanup-on-fail", false, "allow deletion of new resources created in this upgrade when upgrade fails")
   226  	f.BoolVar(&client.SubNotes, "render-subchart-notes", false, "if set, render subchart notes along with the parent")
   227  	f.StringVar(&client.Description, "description", "", "add a custom description")
   228  	//addChartPathOptionsFlags(f, &client.ChartPathOptions)
   229  	addValueOptionsFlags(f, valueOpts)
   230  	bindOutputFlag(cmd, &outfmt)
   231  	bindPostRenderFlag(cmd, &client.PostRenderer)
   232  
   233  	origHelpFunc := cmd.HelpFunc()
   234  	cmd.SetHelpFunc(func(cmd *cobra.Command, args []string) {
   235  		hideHelmCommonFlags(cmd)
   236  		origHelpFunc(cmd, args)
   237  	})
   238  	return cmd
   239  }