fix(pkg/action): load clients after flags have been parsed (#5681)

Signed-off-by: Adam Reese <adam@reese.io>
pull/5601/head
Adam Reese 5 years ago committed by GitHub
parent f39e3da306
commit b8bced2649
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

5
Gopkg.lock generated

@ -1404,11 +1404,12 @@
revision = "44a48934c135b31e4f1c0d12e91d384e1cb2304c" revision = "44a48934c135b31e4f1c0d12e91d384e1cb2304c"
[[projects]] [[projects]]
digest = "1:8774c035808c344c148ba5135b282d487561233ee3be10f6115ea9a9da5e1c56" digest = "1:fe724e5bfc9e388624ccf76b77051c0c7da8695a264b3ab4103de270a8965b18"
name = "k8s.io/client-go" name = "k8s.io/client-go"
packages = [ packages = [
"discovery", "discovery",
"discovery/cached/disk", "discovery/cached/disk",
"discovery/cached/memory",
"discovery/fake", "discovery/fake",
"dynamic", "dynamic",
"dynamic/fake", "dynamic/fake",
@ -1795,7 +1796,6 @@
"github.com/opencontainers/go-digest", "github.com/opencontainers/go-digest",
"github.com/opencontainers/image-spec/specs-go/v1", "github.com/opencontainers/image-spec/specs-go/v1",
"github.com/pkg/errors", "github.com/pkg/errors",
"github.com/sirupsen/logrus",
"github.com/spf13/cobra", "github.com/spf13/cobra",
"github.com/spf13/cobra/doc", "github.com/spf13/cobra/doc",
"github.com/spf13/pflag", "github.com/spf13/pflag",
@ -1832,6 +1832,7 @@
"k8s.io/cli-runtime/pkg/genericclioptions", "k8s.io/cli-runtime/pkg/genericclioptions",
"k8s.io/cli-runtime/pkg/resource", "k8s.io/cli-runtime/pkg/resource",
"k8s.io/client-go/discovery", "k8s.io/client-go/discovery",
"k8s.io/client-go/discovery/cached/memory",
"k8s.io/client-go/kubernetes", "k8s.io/client-go/kubernetes",
"k8s.io/client-go/kubernetes/fake", "k8s.io/client-go/kubernetes/fake",
"k8s.io/client-go/kubernetes/scheme", "k8s.io/client-go/kubernetes/scheme",

@ -91,9 +91,9 @@ func newActionConfig(allNamespaces bool) *action.Configuration {
} }
return &action.Configuration{ return &action.Configuration{
RESTClientGetter: kubeConfig(),
KubeClient: kc, KubeClient: kc,
Releases: store, Releases: store,
Discovery: clientset.Discovery(),
Log: logf, Log: logf,
} }
} }

@ -26,10 +26,10 @@ import (
shellwords "github.com/mattn/go-shellwords" shellwords "github.com/mattn/go-shellwords"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/client-go/kubernetes/fake"
"helm.sh/helm/internal/test" "helm.sh/helm/internal/test"
"helm.sh/helm/pkg/action" "helm.sh/helm/pkg/action"
"helm.sh/helm/pkg/chartutil"
"helm.sh/helm/pkg/helmpath" "helm.sh/helm/pkg/helmpath"
"helm.sh/helm/pkg/kube" "helm.sh/helm/pkg/kube"
"helm.sh/helm/pkg/release" "helm.sh/helm/pkg/release"
@ -117,7 +117,7 @@ func executeActionCommandC(store *storage.Storage, cmd string) (*cobra.Command,
actionConfig := &action.Configuration{ actionConfig := &action.Configuration{
Releases: store, Releases: store,
KubeClient: &kube.PrintingKubeClient{Out: ioutil.Discard}, KubeClient: &kube.PrintingKubeClient{Out: ioutil.Discard},
Discovery: fake.NewSimpleClientset().Discovery(), Capabilities: chartutil.DefaultCapabilities,
Log: func(format string, v ...interface{}) {}, Log: func(format string, v ...interface{}) {},
} }

@ -23,10 +23,10 @@ import (
"strings" "strings"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/client-go/kubernetes/fake"
"helm.sh/helm/cmd/helm/require" "helm.sh/helm/cmd/helm/require"
"helm.sh/helm/pkg/action" "helm.sh/helm/pkg/action"
"helm.sh/helm/pkg/chartutil"
"helm.sh/helm/pkg/kube" "helm.sh/helm/pkg/kube"
"helm.sh/helm/pkg/storage" "helm.sh/helm/pkg/storage"
"helm.sh/helm/pkg/storage/driver" "helm.sh/helm/pkg/storage/driver"
@ -50,7 +50,7 @@ func newTemplateCmd(out io.Writer) *cobra.Command {
// Add mock objects in here so it doesn't use Kube API server // Add mock objects in here so it doesn't use Kube API server
Releases: storage.Init(driver.NewMemory()), Releases: storage.Init(driver.NewMemory()),
KubeClient: &kube.PrintingKubeClient{Out: ioutil.Discard}, KubeClient: &kube.PrintingKubeClient{Out: ioutil.Discard},
Discovery: fake.NewSimpleClientset().Discovery(), Capabilities: chartutil.DefaultCapabilities,
Log: func(format string, v ...interface{}) { Log: func(format string, v ...interface{}) {
fmt.Fprintf(out, format, v...) fmt.Fprintf(out, format, v...)
}, },

@ -21,8 +21,10 @@ import (
"time" "time"
"github.com/pkg/errors" "github.com/pkg/errors"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/discovery" "k8s.io/client-go/discovery"
"k8s.io/client-go/rest"
"helm.sh/helm/pkg/chartutil" "helm.sh/helm/pkg/chartutil"
"helm.sh/helm/pkg/kube" "helm.sh/helm/pkg/kube"
@ -61,8 +63,8 @@ var ValidName = regexp.MustCompile("^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])+
// Configuration injects the dependencies that all actions share. // Configuration injects the dependencies that all actions share.
type Configuration struct { type Configuration struct {
// Discovery contains a discovery client // RESTClientGetter is an interface that loads Kuberbetes clients.
Discovery discovery.DiscoveryInterface RESTClientGetter RESTClientGetter
// Releases stores records of releases. // Releases stores records of releases.
Releases *storage.Storage Releases *storage.Storage
@ -73,17 +75,37 @@ type Configuration struct {
// RegistryClient is a client for working with registries // RegistryClient is a client for working with registries
RegistryClient *registry.Client RegistryClient *registry.Client
// Capabilities describes the capabilities of the Kubernetes cluster.
Capabilities *chartutil.Capabilities Capabilities *chartutil.Capabilities
Log func(string, ...interface{}) Log func(string, ...interface{})
} }
// capabilities builds a Capabilities from discovery information. // capabilities builds a Capabilities from discovery information.
func (c *Configuration) capabilities() *chartutil.Capabilities { func (c *Configuration) getCapabilities() (*chartutil.Capabilities, error) {
if c.Capabilities == nil { if c.Capabilities != nil {
return chartutil.DefaultCapabilities return c.Capabilities, nil
} }
return c.Capabilities
dc, err := c.RESTClientGetter.ToDiscoveryClient()
if err != nil {
return nil, errors.Wrap(err, "could not get Kubernetes discovery client")
}
kubeVersion, err := dc.ServerVersion()
if err != nil {
return nil, errors.Wrap(err, "could not get server version from Kubernetes")
}
apiVersions, err := GetVersionSet(dc)
if err != nil {
return nil, errors.Wrap(err, "could not get apiVersions from Kubernetes")
}
c.Capabilities = &chartutil.Capabilities{
KubeVersion: kubeVersion,
APIVersions: apiVersions,
}
return c.Capabilities, nil
} }
// Now generates a timestamp // Now generates a timestamp
@ -131,3 +153,9 @@ func (c *Configuration) recordRelease(r *release.Release) {
c.Log("warning: Failed to update release %s: %s", r.Name, err) c.Log("warning: Failed to update release %s: %s", r.Name, err)
} }
} }
type RESTClientGetter interface {
ToRESTConfig() (*rest.Config, error)
ToDiscoveryClient() (discovery.CachedDiscoveryInterface, error)
ToRESTMapper() (meta.RESTMapper, error)
}

@ -23,9 +23,9 @@ import (
"time" "time"
"github.com/pkg/errors" "github.com/pkg/errors"
"k8s.io/client-go/kubernetes/fake"
"helm.sh/helm/pkg/chart" "helm.sh/helm/pkg/chart"
"helm.sh/helm/pkg/chartutil"
"helm.sh/helm/pkg/kube" "helm.sh/helm/pkg/kube"
"helm.sh/helm/pkg/release" "helm.sh/helm/pkg/release"
"helm.sh/helm/pkg/storage" "helm.sh/helm/pkg/storage"
@ -40,7 +40,7 @@ func actionConfigFixture(t *testing.T) *Configuration {
return &Configuration{ return &Configuration{
Releases: storage.Init(driver.NewMemory()), Releases: storage.Init(driver.NewMemory()),
KubeClient: &kube.PrintingKubeClient{Out: ioutil.Discard}, KubeClient: &kube.PrintingKubeClient{Out: ioutil.Discard},
Discovery: fake.NewSimpleClientset().Discovery(), Capabilities: chartutil.DefaultCapabilities,
Log: func(format string, v ...interface{}) { Log: func(format string, v ...interface{}) {
t.Helper() t.Helper()
if *verbose { if *verbose {

@ -115,7 +115,10 @@ func (i *Install) Run(chrt *chart.Chart) (*release.Release, error) {
return nil, err return nil, err
} }
caps := i.cfg.capabilities() caps, err := i.cfg.getCapabilities()
if err != nil {
return nil, err
}
options := chartutil.ReleaseOptions{ options := chartutil.ReleaseOptions{
Name: i.ReleaseName, Name: i.ReleaseName,
@ -295,7 +298,10 @@ func (c *Configuration) renderResources(ch *chart.Chart, values chartutil.Values
hs := []*release.Hook{} hs := []*release.Hook{}
b := bytes.NewBuffer(nil) b := bytes.NewBuffer(nil)
caps := c.capabilities() caps, err := c.getCapabilities()
if err != nil {
return hs, b, "", err
}
if ch.Metadata.KubeVersion != "" { if ch.Metadata.KubeVersion != "" {
gitVersion := caps.KubeVersion.String() gitVersion := caps.KubeVersion.String()

@ -203,7 +203,7 @@ func (u *Uninstall) execHook(hs []*release.Hook, namespace, hook string) error {
// deleteRelease deletes the release and returns manifests that were kept in the deletion process // deleteRelease deletes the release and returns manifests that were kept in the deletion process
func (u *Uninstall) deleteRelease(rel *release.Release) (kept string, errs []error) { func (u *Uninstall) deleteRelease(rel *release.Release) (kept string, errs []error) {
caps, err := newCapabilities(u.cfg.Discovery) caps, err := u.cfg.getCapabilities()
if err != nil { if err != nil {
return rel.Manifest, []error{errors.Wrap(err, "could not get apiVersions from Kubernetes")} return rel.Manifest, []error{errors.Wrap(err, "could not get apiVersions from Kubernetes")}
} }

@ -23,7 +23,6 @@ import (
"time" "time"
"github.com/pkg/errors" "github.com/pkg/errors"
"k8s.io/client-go/discovery"
"helm.sh/helm/pkg/chart" "helm.sh/helm/pkg/chart"
"helm.sh/helm/pkg/chartutil" "helm.sh/helm/pkg/chartutil"
@ -150,7 +149,7 @@ func (u *Upgrade) prepareUpgrade(name string, chart *chart.Chart) (*release.Rele
IsUpgrade: true, IsUpgrade: true,
} }
caps, err := newCapabilities(u.cfg.Discovery) caps, err := u.cfg.getCapabilities()
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@ -275,23 +274,6 @@ func (u *Upgrade) reuseValues(chart *chart.Chart, current *release.Release) erro
return nil return nil
} }
func newCapabilities(dc discovery.DiscoveryInterface) (*chartutil.Capabilities, error) {
kubeVersion, err := dc.ServerVersion()
if err != nil {
return nil, err
}
apiVersions, err := GetVersionSet(dc)
if err != nil {
return nil, errors.Wrap(err, "could not get apiVersions from Kubernetes")
}
return &chartutil.Capabilities{
KubeVersion: kubeVersion,
APIVersions: apiVersions,
}, nil
}
func validateManifest(c kube.KubernetesClient, ns string, manifest []byte) error { func validateManifest(c kube.KubernetesClient, ns string, manifest []byte) error {
_, err := c.BuildUnstructured(ns, bytes.NewReader(manifest)) _, err := c.BuildUnstructured(ns, bytes.NewReader(manifest))
return err return err

Loading…
Cancel
Save