From 0c231a651d5494c307e6ddc16d4cd15f1a3716db Mon Sep 17 00:00:00 2001 From: Eric Latham Date: Fri, 14 Jun 2024 14:49:12 -0500 Subject: [PATCH] Introduce --disable-fetching-api-versions for install and upgrade Signed-off-by: Eric Latham --- cmd/helm/install.go | 1 + cmd/helm/upgrade.go | 2 ++ pkg/action/action.go | 26 ++++++++++++++++---------- pkg/action/install.go | 6 ++++-- pkg/action/uninstall.go | 2 +- pkg/action/upgrade.go | 6 ++++-- 6 files changed, 28 insertions(+), 15 deletions(-) diff --git a/cmd/helm/install.go b/cmd/helm/install.go index ed3f74274..bd0ac3279 100644 --- a/cmd/helm/install.go +++ b/cmd/helm/install.go @@ -200,6 +200,7 @@ func addInstallFlags(cmd *cobra.Command, f *pflag.FlagSet, client *action.Instal f.StringToStringVarP(&client.Labels, "labels", "l", nil, "Labels that would be added to release metadata. Should be divided by comma.") f.BoolVar(&client.EnableDNS, "enable-dns", false, "enable DNS lookups when rendering templates") f.BoolVar(&client.HideNotes, "hide-notes", false, "if set, do not show notes in install output. Does not affect presence in chart metadata") + f.BoolVar(&client.DisableFetchingAPIVersions, "disable-fetching-api-versions", false, "if set, the installation process will populate the built-in Capabilities.APIVersions template object with a default version set instead of fetching the full set from the Kubernetes API server") addValueOptionsFlags(f, valueOpts) addChartPathOptionsFlags(f, &client.ChartPathOptions) diff --git a/cmd/helm/upgrade.go b/cmd/helm/upgrade.go index 23472619d..34651161c 100644 --- a/cmd/helm/upgrade.go +++ b/cmd/helm/upgrade.go @@ -150,6 +150,7 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { instClient.Labels = client.Labels instClient.EnableDNS = client.EnableDNS instClient.HideSecret = client.HideSecret + instClient.DisableFetchingAPIVersions = client.DisableFetchingAPIVersions if isReleaseUninstalled(versions) { instClient.Replace = true @@ -278,6 +279,7 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { f.StringVar(&client.Description, "description", "", "add a custom description") f.BoolVar(&client.DependencyUpdate, "dependency-update", false, "update dependencies if they are missing before installing the chart") f.BoolVar(&client.EnableDNS, "enable-dns", false, "enable DNS lookups when rendering templates") + f.BoolVar(&client.DisableFetchingAPIVersions, "disable-fetching-api-versions", false, "if set, the upgrade process will populate the built-in Capabilities.APIVersions template object with a default version set instead of fetching the full set from the Kubernetes API server") addChartPathOptionsFlags(f, &client.ChartPathOptions) addValueOptionsFlags(f, valueOpts) bindOutputFlag(cmd, &outfmt) diff --git a/pkg/action/action.go b/pkg/action/action.go index 863c48f07..e69f47807 100644 --- a/pkg/action/action.go +++ b/pkg/action/action.go @@ -103,11 +103,11 @@ type Configuration struct { // TODO: As part of the refactor the duplicate code in cmd/helm/template.go should be removed // // This code has to do with writing files to disk. -func (cfg *Configuration) renderResources(ch *chart.Chart, values chartutil.Values, releaseName, outputDir string, subNotes, useReleaseName, includeCrds bool, pr postrender.PostRenderer, interactWithRemote, enableDNS, hideSecret bool) ([]*release.Hook, *bytes.Buffer, string, error) { +func (cfg *Configuration) renderResources(ch *chart.Chart, values chartutil.Values, releaseName, outputDir string, subNotes, useReleaseName, includeCrds bool, pr postrender.PostRenderer, interactWithRemote, enableDNS, hideSecret, fetchApiVersions bool) ([]*release.Hook, *bytes.Buffer, string, error) { hs := []*release.Hook{} b := bytes.NewBuffer(nil) - caps, err := cfg.getCapabilities() + caps, err := cfg.getCapabilities(fetchApiVersions) if err != nil { return hs, b, "", err } @@ -243,7 +243,7 @@ type RESTClientGetter interface { type DebugLog func(format string, v ...interface{}) // capabilities builds a Capabilities from discovery information. -func (cfg *Configuration) getCapabilities() (*chartutil.Capabilities, error) { +func (cfg *Configuration) getCapabilities(fetchApiVersions bool) (*chartutil.Capabilities, error) { if cfg.Capabilities != nil { return cfg.Capabilities, nil } @@ -262,14 +262,20 @@ func (cfg *Configuration) getCapabilities() (*chartutil.Capabilities, error) { // We trap that error here and print a warning. But since the discovery client continues // building the API object, it is correctly populated with all valid APIs. // See https://github.com/kubernetes/kubernetes/issues/72051#issuecomment-521157642 - apiVersions, err := GetVersionSet(dc) - if err != nil { - if discovery.IsGroupDiscoveryFailedError(err) { - cfg.Log("WARNING: The Kubernetes server has an orphaned API service. Server reports: %s", err) - cfg.Log("WARNING: To fix this, kubectl delete apiservice ") - } else { - return nil, errors.Wrap(err, "could not get apiVersions from Kubernetes") + var apiVersions chartutil.VersionSet + if fetchApiVersions { + apiVersions, err = GetVersionSet(dc) + if err != nil { + if discovery.IsGroupDiscoveryFailedError(err) { + cfg.Log("WARNING: The Kubernetes server has an orphaned API service. Server reports: %s", err) + cfg.Log("WARNING: To fix this, kubectl delete apiservice ") + } else { + return nil, errors.Wrap(err, "could not get apiVersions from Kubernetes") + } } + } else { + cfg.Log("WARNING: Fetching Kubernetes server-supported API versions is disabled; built-in template object Capabilities.APIVersions will contain the default version set") + apiVersions = chartutil.DefaultVersionSet } cfg.Capabilities = &chartutil.Capabilities{ diff --git a/pkg/action/install.go b/pkg/action/install.go index 6dce3ccbb..4c4ce9b40 100644 --- a/pkg/action/install.go +++ b/pkg/action/install.go @@ -112,6 +112,8 @@ type Install struct { PostRenderer postrender.PostRenderer // Lock to control raceconditions when the process receives a SIGTERM Lock sync.Mutex + // DisableFetchingAPIVersions controls whether Capabilities.APIVersions is fetched from the API server + DisableFetchingAPIVersions bool } // ChartPathOptions captures common options used for controlling chart paths @@ -284,7 +286,7 @@ func (i *Install) RunWithContext(ctx context.Context, chrt *chart.Chart, vals ma // the user doesn't have to specify both i.Wait = i.Wait || i.Atomic - caps, err := i.cfg.getCapabilities() + caps, err := i.cfg.getCapabilities(!i.DisableFetchingAPIVersions) if err != nil { return nil, err } @@ -310,7 +312,7 @@ func (i *Install) RunWithContext(ctx context.Context, chrt *chart.Chart, vals ma rel := i.createRelease(chrt, vals, i.Labels) var manifestDoc *bytes.Buffer - rel.Hooks, manifestDoc, rel.Info.Notes, err = i.cfg.renderResources(chrt, valuesToRender, i.ReleaseName, i.OutputDir, i.SubNotes, i.UseReleaseName, i.IncludeCRDs, i.PostRenderer, interactWithRemote, i.EnableDNS, i.HideSecret) + rel.Hooks, manifestDoc, rel.Info.Notes, err = i.cfg.renderResources(chrt, valuesToRender, i.ReleaseName, i.OutputDir, i.SubNotes, i.UseReleaseName, i.IncludeCRDs, i.PostRenderer, interactWithRemote, i.EnableDNS, i.HideSecret, !i.DisableFetchingAPIVersions) // Even for errors, attach this if available if manifestDoc != nil { rel.Manifest = manifestDoc.String() diff --git a/pkg/action/uninstall.go b/pkg/action/uninstall.go index 40d82243e..ff619ec58 100644 --- a/pkg/action/uninstall.go +++ b/pkg/action/uninstall.go @@ -196,7 +196,7 @@ func joinErrors(errs []error) string { // deleteRelease deletes the release and returns list of delete resources and manifests that were kept in the deletion process func (u *Uninstall) deleteRelease(rel *release.Release) (kube.ResourceList, string, []error) { var errs []error - caps, err := u.cfg.getCapabilities() + caps, err := u.cfg.getCapabilities(true) if err != nil { return nil, rel.Manifest, []error{errors.Wrap(err, "could not get apiVersions from Kubernetes")} } diff --git a/pkg/action/upgrade.go b/pkg/action/upgrade.go index 6d26a754e..adf0c5645 100644 --- a/pkg/action/upgrade.go +++ b/pkg/action/upgrade.go @@ -115,6 +115,8 @@ type Upgrade struct { Lock sync.Mutex // Enable DNS lookups when rendering templates EnableDNS bool + // DisableFetchingAPIVersions controls whether Capabilities.APIVersions is fetched from the API server + DisableFetchingAPIVersions bool } type resultMessage struct { @@ -254,7 +256,7 @@ func (u *Upgrade) prepareUpgrade(name string, chart *chart.Chart, vals map[strin IsUpgrade: true, } - caps, err := u.cfg.getCapabilities() + caps, err := u.cfg.getCapabilities(!u.DisableFetchingAPIVersions) if err != nil { return nil, nil, err } @@ -269,7 +271,7 @@ func (u *Upgrade) prepareUpgrade(name string, chart *chart.Chart, vals map[strin interactWithRemote = true } - hooks, manifestDoc, notesTxt, err := u.cfg.renderResources(chart, valuesToRender, "", "", u.SubNotes, false, false, u.PostRenderer, interactWithRemote, u.EnableDNS, u.HideSecret) + hooks, manifestDoc, notesTxt, err := u.cfg.renderResources(chart, valuesToRender, "", "", u.SubNotes, false, false, u.PostRenderer, interactWithRemote, u.EnableDNS, u.HideSecret, !u.DisableFetchingAPIVersions) if err != nil { return nil, nil, err }