From 451e2158ad24594d8c67e2e4a99aefc5ffa84a9f Mon Sep 17 00:00:00 2001 From: Nguyen Hai Truong Date: Mon, 6 Jan 2020 22:54:47 +0700 Subject: [PATCH 01/66] Remove duplicated words (#7336) Although it is spelling mistakes, it might make an affects while reading. Signed-off-by: Nguyen Hai Truong Signed-off-by: EItanya --- internal/third_party/dep/fs/fs_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/internal/third_party/dep/fs/fs_test.go b/internal/third_party/dep/fs/fs_test.go index bf4b803f8..a9678d8c1 100644 --- a/internal/third_party/dep/fs/fs_test.go +++ b/internal/third_party/dep/fs/fs_test.go @@ -170,7 +170,7 @@ func TestCopyDir(t *testing.T) { func TestCopyDirFail_SrcInaccessible(t *testing.T) { if runtime.GOOS == "windows" { // XXX: setting permissions works differently in - // Microsoft Windows. Skipping this this until a + // Microsoft Windows. Skipping this until a // compatible implementation is provided. t.Skip("skipping on windows") } @@ -209,7 +209,7 @@ func TestCopyDirFail_SrcInaccessible(t *testing.T) { func TestCopyDirFail_DstInaccessible(t *testing.T) { if runtime.GOOS == "windows" { // XXX: setting permissions works differently in - // Microsoft Windows. Skipping this this until a + // Microsoft Windows. Skipping this until a // compatible implementation is provided. t.Skip("skipping on windows") } @@ -309,7 +309,7 @@ func TestCopyDirFailOpen(t *testing.T) { // Microsoft Windows. os.Chmod(..., 0222) below is not // enough for the file to be readonly, and os.Chmod(..., // 0000) returns an invalid argument error. Skipping - // this this until a compatible implementation is + // this until a compatible implementation is // provided. t.Skip("skipping on windows") } @@ -478,7 +478,7 @@ func TestCopyFileSymlink(t *testing.T) { func TestCopyFileFail(t *testing.T) { if runtime.GOOS == "windows" { // XXX: setting permissions works differently in - // Microsoft Windows. Skipping this this until a + // Microsoft Windows. Skipping this until a // compatible implementation is provided. t.Skip("skipping on windows") } @@ -521,7 +521,7 @@ func TestCopyFileFail(t *testing.T) { } // setupInaccessibleDir creates a temporary location with a single -// directory in it, in such a way that that directory is not accessible +// directory in it, in such a way that directory is not accessible // after this function returns. // // op is called with the directory as argument, so that it can create From b7ff1e29327d33b6fe9b44b11d84c182d1adea45 Mon Sep 17 00:00:00 2001 From: "Jorge I. Gasca" <42793610+jorge-gasca@users.noreply.github.com> Date: Tue, 7 Jan 2020 12:25:15 -0500 Subject: [PATCH 02/66] fix(cmd): Fixes logging on action conf init error (#6909) * fix(cmd): Fixes logging on action conf init error Errors relating to initializing the action config cause helm to exit silently, except when in debug mode. This now emits the useful error. Closes #6863 Signed-off-by: Jorge Gasca * Remove unnecessary formatting of err struct Signed-off-by: Jorge Gasca Signed-off-by: EItanya --- cmd/helm/helm.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cmd/helm/helm.go b/cmd/helm/helm.go index 2c3c9e401..112d5123f 100644 --- a/cmd/helm/helm.go +++ b/cmd/helm/helm.go @@ -68,8 +68,7 @@ func main() { cmd := newRootCmd(actionConfig, os.Stdout, os.Args[1:]) if err := actionConfig.Init(settings.RESTClientGetter(), settings.Namespace(), os.Getenv("HELM_DRIVER"), debug); err != nil { - debug("%+v", err) - os.Exit(1) + log.Fatal(err) } if err := cmd.Execute(); err != nil { From 00769c4512c9c145eafb84f60e8a473de83b0209 Mon Sep 17 00:00:00 2001 From: Hu Shuai Date: Wed, 8 Jan 2020 17:19:00 +0800 Subject: [PATCH 03/66] Fix a typo "update" -> "updates" (#7346) Signed-off-by: Hu Shuai Signed-off-by: EItanya --- pkg/storage/storage.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/storage/storage.go b/pkg/storage/storage.go index 58a7eb06f..6528c48ba 100644 --- a/pkg/storage/storage.go +++ b/pkg/storage/storage.go @@ -66,7 +66,7 @@ func (s *Storage) Create(rls *rspb.Release) error { return s.Driver.Create(makeKey(rls.Name, rls.Version), rls) } -// Update update the release in storage. An error is returned if the +// Update updates the release in storage. An error is returned if the // storage backend fails to update the release or if the release // does not exist. func (s *Storage) Update(rls *rspb.Release) error { From 17dc43f0547d4fd7205de07428b97fbc4a5276fd Mon Sep 17 00:00:00 2001 From: EItanya Date: Wed, 8 Jan 2020 13:21:31 -0500 Subject: [PATCH 04/66] added config file string Signed-off-by: EItanya --- cmd/helm/root.go | 1 + internal/experimental/registry/client.go | 18 +++++++++++------- internal/experimental/registry/client_opts.go | 7 +++++++ 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/cmd/helm/root.go b/cmd/helm/root.go index 3405299fd..ea0654c4b 100644 --- a/cmd/helm/root.go +++ b/cmd/helm/root.go @@ -416,6 +416,7 @@ func newRootCmd(actionConfig *action.Configuration, out io.Writer, args []string registryClient, err := registry.NewClient( registry.ClientOptDebug(settings.Debug), registry.ClientOptWriter(out), + registry.ClientOptCredentialsFile(settings.RepositoryConfig), ) if err != nil { // TODO: don't panic here, refactor newRootCmd to return error diff --git a/internal/experimental/registry/client.go b/internal/experimental/registry/client.go index d52d9f3e0..48d4d9ecc 100644 --- a/internal/experimental/registry/client.go +++ b/internal/experimental/registry/client.go @@ -41,11 +41,13 @@ const ( type ( // Client works with OCI-compliant registries and local Helm chart cache Client struct { - debug bool - out io.Writer - authorizer *Authorizer - resolver *Resolver - cache *Cache + debug bool + // path to repository config file e.g. ~/.docker/config.json + credentialsFile string + out io.Writer + authorizer *Authorizer + resolver *Resolver + cache *Cache } ) @@ -58,9 +60,11 @@ func NewClient(opts ...ClientOption) (*Client, error) { opt(client) } // set defaults if fields are missing + if client.credentialsFile == "" { + client.credentialsFile = helmpath.CachePath("registry", CredentialsFileBasename) + } if client.authorizer == nil { - credentialsFile := helmpath.CachePath("registry", CredentialsFileBasename) - authClient, err := auth.NewClient(credentialsFile) + authClient, err := auth.NewClient(client.credentialsFile) if err != nil { return nil, err } diff --git a/internal/experimental/registry/client_opts.go b/internal/experimental/registry/client_opts.go index cd295813a..76b527492 100644 --- a/internal/experimental/registry/client_opts.go +++ b/internal/experimental/registry/client_opts.go @@ -60,3 +60,10 @@ func ClientOptCache(cache *Cache) ClientOption { client.cache = cache } } + +// ClientOptCache returns a function that sets the cache setting on a client options set +func ClientOptCredentialsFile(credentialsFile string) ClientOption { + return func(client *Client) { + client.credentialsFile = credentialsFile + } +} From 2f534f97424ce4eaa3356e199e453e94bd65b4c6 Mon Sep 17 00:00:00 2001 From: EItanya Date: Wed, 8 Jan 2020 14:00:51 -0500 Subject: [PATCH 05/66] fix test Signed-off-by: EItanya --- cmd/helm/root.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/helm/root.go b/cmd/helm/root.go index ea0654c4b..1cee11458 100644 --- a/cmd/helm/root.go +++ b/cmd/helm/root.go @@ -416,7 +416,7 @@ func newRootCmd(actionConfig *action.Configuration, out io.Writer, args []string registryClient, err := registry.NewClient( registry.ClientOptDebug(settings.Debug), registry.ClientOptWriter(out), - registry.ClientOptCredentialsFile(settings.RepositoryConfig), + registry.ClientOptCredentialsFile(settings.RegistryConfig), ) if err != nil { // TODO: don't panic here, refactor newRootCmd to return error From 640d527190376a8b4945575f767065ebd47a83cb Mon Sep 17 00:00:00 2001 From: EItanya Date: Wed, 8 Jan 2020 14:03:06 -0500 Subject: [PATCH 06/66] removed panic, and replaced with error Signed-off-by: EItanya --- cmd/helm/helm.go | 5 ++++- cmd/helm/helm_test.go | 6 +++++- cmd/helm/root.go | 7 +++---- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/cmd/helm/helm.go b/cmd/helm/helm.go index 112d5123f..952719623 100644 --- a/cmd/helm/helm.go +++ b/cmd/helm/helm.go @@ -65,7 +65,10 @@ func main() { initKubeLogs() actionConfig := new(action.Configuration) - cmd := newRootCmd(actionConfig, os.Stdout, os.Args[1:]) + cmd, err := newRootCmd(actionConfig, os.Stdout, os.Args[1:]) + if err != nil { + log.Fatal(err) + } if err := actionConfig.Init(settings.RESTClientGetter(), settings.Namespace(), os.Getenv("HELM_DRIVER"), debug); err != nil { log.Fatal(err) diff --git a/cmd/helm/helm_test.go b/cmd/helm/helm_test.go index 924e8e9d3..20e7ed3e9 100644 --- a/cmd/helm/helm_test.go +++ b/cmd/helm/helm_test.go @@ -107,7 +107,11 @@ func executeActionCommandC(store *storage.Storage, cmd string) (*cobra.Command, Log: func(format string, v ...interface{}) {}, } - root := newRootCmd(actionConfig, buf, args) + root, err := newRootCmd(actionConfig, buf, args) + if err != nil { + return nil, "", err + } + root.SetOutput(buf) root.SetArgs(args) diff --git a/cmd/helm/root.go b/cmd/helm/root.go index 1cee11458..45fbe544d 100644 --- a/cmd/helm/root.go +++ b/cmd/helm/root.go @@ -345,7 +345,7 @@ By default, the default directories depend on the Operating System. The defaults +------------------+---------------------------+--------------------------------+-------------------------+ ` -func newRootCmd(actionConfig *action.Configuration, out io.Writer, args []string) *cobra.Command { +func newRootCmd(actionConfig *action.Configuration, out io.Writer, args []string) (*cobra.Command, error) { cmd := &cobra.Command{ Use: "helm", Short: "The Helm package manager for Kubernetes.", @@ -419,8 +419,7 @@ func newRootCmd(actionConfig *action.Configuration, out io.Writer, args []string registry.ClientOptCredentialsFile(settings.RegistryConfig), ) if err != nil { - // TODO: don't panic here, refactor newRootCmd to return error - panic(err) + return nil, err } actionConfig.RegistryClient = registryClient cmd.AddCommand( @@ -431,5 +430,5 @@ func newRootCmd(actionConfig *action.Configuration, out io.Writer, args []string // Find and add plugins loadPlugins(cmd, out) - return cmd + return cmd, nil } From f604105547dc260f4388792de44a6eb9d2a1353f Mon Sep 17 00:00:00 2001 From: EItanya Date: Wed, 8 Jan 2020 14:11:06 -0500 Subject: [PATCH 07/66] fixed to mirror master Signed-off-by: EItanya --- cmd/helm/helm.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cmd/helm/helm.go b/cmd/helm/helm.go index 952719623..ead4a2c49 100644 --- a/cmd/helm/helm.go +++ b/cmd/helm/helm.go @@ -67,11 +67,13 @@ func main() { actionConfig := new(action.Configuration) cmd, err := newRootCmd(actionConfig, os.Stdout, os.Args[1:]) if err != nil { - log.Fatal(err) + debug("%+v", err) + os.Exit(1) } if err := actionConfig.Init(settings.RESTClientGetter(), settings.Namespace(), os.Getenv("HELM_DRIVER"), debug); err != nil { - log.Fatal(err) + debug("%+v", err) + os.Exit(1) } if err := cmd.Execute(); err != nil { From de1996e500c75faccbb8aadc1d2e8b788f83ac3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Lindh=C3=A9?= Date: Fri, 15 Nov 2019 12:45:47 +0100 Subject: [PATCH 08/66] Add comments about release Version variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I was looking into the `get` command, and got tripped up by the `Version` variable. It was unclear to me what Version represents, since it's called REVISION when doing e.g., `helm list`. But even after knowing this, it was not very clear to me why we (implicitly) set the Version variable to 0 but never seem to use it. `mhickey` explained to me on Slack that this gets the latest revision of the release. Makes sense, but I added a comment about that too, to clarify. Signed-off-by: Andreas Lindhé --- pkg/action/get.go | 1 + pkg/release/release.go | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/action/get.go b/pkg/action/get.go index c776eb696..f44b53307 100644 --- a/pkg/action/get.go +++ b/pkg/action/get.go @@ -26,6 +26,7 @@ import ( type Get struct { cfg *Configuration + // Initializing Version to 0 will get the latest revision of the release. Version int } diff --git a/pkg/release/release.go b/pkg/release/release.go index a436998aa..8582a86f3 100644 --- a/pkg/release/release.go +++ b/pkg/release/release.go @@ -33,7 +33,7 @@ type Release struct { Manifest string `json:"manifest,omitempty"` // Hooks are all of the hooks declared for this release. Hooks []*Hook `json:"hooks,omitempty"` - // Version is an int which represents the version of the release. + // Version is an int which represents the revision of the release. Version int `json:"version,omitempty"` // Namespace is the kubernetes namespace of the release. Namespace string `json:"namespace,omitempty"` From 918deeef181f20ea640bc562cef69d209493cbab Mon Sep 17 00:00:00 2001 From: Matthias Riegler Date: Fri, 1 May 2020 13:21:44 +0200 Subject: [PATCH 09/66] added option --insecure-skip-tls-verify for helm pull, addresses #7875 Signed-off-by: Matthias Riegler --- cmd/helm/flags.go | 1 + pkg/action/install.go | 19 ++++++++++--------- pkg/action/pull.go | 1 + 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/cmd/helm/flags.go b/cmd/helm/flags.go index 246cb0dd5..d35a05fec 100644 --- a/cmd/helm/flags.go +++ b/cmd/helm/flags.go @@ -49,6 +49,7 @@ func addChartPathOptionsFlags(f *pflag.FlagSet, c *action.ChartPathOptions) { f.StringVar(&c.Password, "password", "", "chart repository password where to locate the requested chart") f.StringVar(&c.CertFile, "cert-file", "", "identify HTTPS client using this SSL certificate file") f.StringVar(&c.KeyFile, "key-file", "", "identify HTTPS client using this SSL key file") + f.BoolVar(&c.InsecureSkipTLSverify, "insecure-skip-tls-verify", false, "skip tls certificate checks for the chart download") f.StringVar(&c.CaFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle") } diff --git a/pkg/action/install.go b/pkg/action/install.go index 10a9644dd..cb5318965 100644 --- a/pkg/action/install.go +++ b/pkg/action/install.go @@ -104,15 +104,16 @@ type Install struct { // ChartPathOptions captures common options used for controlling chart paths type ChartPathOptions struct { - CaFile string // --ca-file - CertFile string // --cert-file - KeyFile string // --key-file - Keyring string // --keyring - Password string // --password - RepoURL string // --repo - Username string // --username - Verify bool // --verify - Version string // --version + CaFile string // --ca-file + CertFile string // --cert-file + KeyFile string // --key-file + InsecureSkipTLSverify bool // --insecure-skip-verify + Keyring string // --keyring + Password string // --password + RepoURL string // --repo + Username string // --username + Verify bool // --verify + Version string // --version } // NewInstall creates a new Install object with the given configuration. diff --git a/pkg/action/pull.go b/pkg/action/pull.go index ee20bbe83..a46e98bae 100644 --- a/pkg/action/pull.go +++ b/pkg/action/pull.go @@ -64,6 +64,7 @@ func (p *Pull) Run(chartRef string) (string, error) { Options: []getter.Option{ getter.WithBasicAuth(p.Username, p.Password), getter.WithTLSClientConfig(p.CertFile, p.KeyFile, p.CaFile), + getter.WithInsecureSkipVerifyTLS(p.InsecureSkipTLSverify), }, RepositoryConfig: p.Settings.RepositoryConfig, RepositoryCache: p.Settings.RepositoryCache, From 8ff7801e0c3d902a5fc4129aaaf60aa97c7ba4fd Mon Sep 17 00:00:00 2001 From: Matthias Riegler Date: Fri, 1 May 2020 14:57:36 +0200 Subject: [PATCH 10/66] added option --insecure-skip-tls-verify for helm install, addresses #7875 Signed-off-by: Matthias Riegler --- pkg/action/install.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/action/install.go b/pkg/action/install.go index cb5318965..4a8bf1835 100644 --- a/pkg/action/install.go +++ b/pkg/action/install.go @@ -641,6 +641,7 @@ func (c *ChartPathOptions) LocateChart(name string, settings *cli.EnvSettings) ( Options: []getter.Option{ getter.WithBasicAuth(c.Username, c.Password), getter.WithTLSClientConfig(c.CertFile, c.KeyFile, c.CaFile), + getter.WithInsecureSkipVerifyTLS(c.InsecureSkipTLSverify), }, RepositoryConfig: settings.RepositoryConfig, RepositoryCache: settings.RepositoryCache, From b473f8adec7dab35614f0c20b0738a865830b443 Mon Sep 17 00:00:00 2001 From: Juned Memon Date: Sat, 9 May 2020 16:57:16 +0530 Subject: [PATCH 11/66] Fixes repo parsing Signed-off-by: Juned Memon --- internal/experimental/registry/reference.go | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/internal/experimental/registry/reference.go b/internal/experimental/registry/reference.go index ced6cf33a..73c409ba2 100644 --- a/internal/experimental/registry/reference.go +++ b/internal/experimental/registry/reference.go @@ -34,6 +34,10 @@ var ( referenceDelimiter = regexp.MustCompile(`[:]`) errEmptyRepo = errors.New("parsed repo was empty") errTooManyColons = errors.New("ref may only contain a single colon character (:) unless specifying a port number") + // ErrInvalid is returned when there is an invalid reference + ErrInvalid = errors.New("invalid reference") + // ErrHostnameRequired is returned when the hostname is required + ErrHostnameRequired = errors.New("hostname required") ) type ( @@ -86,6 +90,7 @@ func (ref *Reference) FullName() string { // validate makes sure the ref meets our criteria func (ref *Reference) validate() error { + err := ref.validateRepo() if err != nil { return err @@ -100,7 +105,15 @@ func (ref *Reference) validateRepo() error { } // Makes sure the repo results in a parsable URL (similar to what is done // with containerd reference parsing) - _, err := url.Parse(ref.Repo) + u, err := url.Parse("dummy://" + ref.Repo) + + if u.Scheme != "dummy" { + return ErrInvalid + } + + if u.Host == "" { + return ErrHostnameRequired + } return err } From 8cb9ab7095c885e1f8d9bea3a28229f58ba59a5e Mon Sep 17 00:00:00 2001 From: Juned Memon Date: Sat, 9 May 2020 18:05:28 +0530 Subject: [PATCH 12/66] Fixes repo parsing Signed-off-by: Juned Memon --- internal/experimental/registry/reference.go | 14 +------------- internal/experimental/registry/reference_test.go | 7 +++++++ 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/internal/experimental/registry/reference.go b/internal/experimental/registry/reference.go index 73c409ba2..13d3d046f 100644 --- a/internal/experimental/registry/reference.go +++ b/internal/experimental/registry/reference.go @@ -34,10 +34,6 @@ var ( referenceDelimiter = regexp.MustCompile(`[:]`) errEmptyRepo = errors.New("parsed repo was empty") errTooManyColons = errors.New("ref may only contain a single colon character (:) unless specifying a port number") - // ErrInvalid is returned when there is an invalid reference - ErrInvalid = errors.New("invalid reference") - // ErrHostnameRequired is returned when the hostname is required - ErrHostnameRequired = errors.New("hostname required") ) type ( @@ -105,15 +101,7 @@ func (ref *Reference) validateRepo() error { } // Makes sure the repo results in a parsable URL (similar to what is done // with containerd reference parsing) - u, err := url.Parse("dummy://" + ref.Repo) - - if u.Scheme != "dummy" { - return ErrInvalid - } - - if u.Host == "" { - return ErrHostnameRequired - } + _, err := url.Parse("dummy://" + ref.Repo) return err } diff --git a/internal/experimental/registry/reference_test.go b/internal/experimental/registry/reference_test.go index bb53ebab8..aae03ad99 100644 --- a/internal/experimental/registry/reference_test.go +++ b/internal/experimental/registry/reference_test.go @@ -81,6 +81,13 @@ func TestParseReference(t *testing.T) { is.Equal("1.5.0", ref.Tag) is.Equal("myrepo:5001/mychart:1.5.0", ref.FullName()) + s = "127.0.0.1:5001/mychart:1.5.0" + ref, err = ParseReference(s) + is.NoError(err) + is.Equal("127.0.0.1:5001/mychart", ref.Repo) + is.Equal("1.5.0", ref.Tag) + is.Equal("127.0.0.1:5001/mychart:1.5.0", ref.FullName()) + s = "localhost:5000/mychart:latest" ref, err = ParseReference(s) is.NoError(err) From 95e9e18ab585ce3e67c373841efae378886189ee Mon Sep 17 00:00:00 2001 From: Juned Memon Date: Mon, 11 May 2020 07:51:45 +0530 Subject: [PATCH 13/66] Removed scheme Signed-off-by: Juned Memon --- internal/experimental/registry/reference.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/experimental/registry/reference.go b/internal/experimental/registry/reference.go index 13d3d046f..ebab29a7e 100644 --- a/internal/experimental/registry/reference.go +++ b/internal/experimental/registry/reference.go @@ -101,7 +101,7 @@ func (ref *Reference) validateRepo() error { } // Makes sure the repo results in a parsable URL (similar to what is done // with containerd reference parsing) - _, err := url.Parse("dummy://" + ref.Repo) + _, err := url.Parse("//" + ref.Repo) return err } From 59eed4e81f840bfa8a5aa69fc6c92471413609eb Mon Sep 17 00:00:00 2001 From: Matt Butcher Date: Tue, 12 May 2020 14:23:25 -0600 Subject: [PATCH 14/66] feat: make the linter coalesce the passed-in values before running values tests (#7984) * fix: make the linter coalesce the passed-in values before running values tests Signed-off-by: Matt Butcher * fixed typo Signed-off-by: Matt Butcher --- internal/test/ensure/ensure.go | 19 +++++++ pkg/lint/lint.go | 2 +- pkg/lint/rules/values.go | 23 +++++++- pkg/lint/rules/values_test.go | 97 ++++++++++++++++++++++++++++++++-- 4 files changed, 135 insertions(+), 6 deletions(-) diff --git a/internal/test/ensure/ensure.go b/internal/test/ensure/ensure.go index 6219ad626..3c0e4575c 100644 --- a/internal/test/ensure/ensure.go +++ b/internal/test/ensure/ensure.go @@ -19,6 +19,7 @@ package ensure import ( "io/ioutil" "os" + "path/filepath" "testing" "helm.sh/helm/v3/pkg/helmpath" @@ -49,3 +50,21 @@ func TempDir(t *testing.T) string { } return d } + +// TempFile ensures a temp file for unit testing purposes. +// +// It returns the path to the directory (to which you will still need to join the filename) +// +// You must clean up the directory that is returned. +// +// tempdir := TempFile(t, "foo", []byte("bar")) +// defer os.RemoveAll(tempdir) +// filename := filepath.Join(tempdir, "foo") +func TempFile(t *testing.T, name string, data []byte) string { + path := TempDir(t) + filename := filepath.Join(path, name) + if err := ioutil.WriteFile(filename, data, 0755); err != nil { + t.Fatal(err) + } + return path +} diff --git a/pkg/lint/lint.go b/pkg/lint/lint.go index d47951671..223ead75a 100644 --- a/pkg/lint/lint.go +++ b/pkg/lint/lint.go @@ -30,7 +30,7 @@ func All(basedir string, values map[string]interface{}, namespace string, strict linter := support.Linter{ChartDir: chartDir} rules.Chartfile(&linter) - rules.Values(&linter) + rules.ValuesWithOverrides(&linter, values) rules.Templates(&linter, values, namespace, strict) return linter } diff --git a/pkg/lint/rules/values.go b/pkg/lint/rules/values.go index 0f202f475..c596687c5 100644 --- a/pkg/lint/rules/values.go +++ b/pkg/lint/rules/values.go @@ -28,7 +28,19 @@ import ( ) // Values lints a chart's values.yaml file. +// +// This function is deprecated and will be removed in Helm 4. func Values(linter *support.Linter) { + ValuesWithOverrides(linter, map[string]interface{}{}) +} + +// ValuesWithOverrides tests the values.yaml file. +// +// If a schema is present in the chart, values are tested against that. Otherwise, +// they are only tested for well-formedness. +// +// If additional values are supplied, they are coalesced into the values in values.yaml. +func ValuesWithOverrides(linter *support.Linter, values map[string]interface{}) { file := "values.yaml" vf := filepath.Join(linter.ChartDir, file) fileExists := linter.RunLinterRule(support.InfoSev, file, validateValuesFileExistence(vf)) @@ -37,7 +49,7 @@ func Values(linter *support.Linter) { return } - linter.RunLinterRule(support.ErrorSev, file, validateValuesFile(vf)) + linter.RunLinterRule(support.ErrorSev, file, validateValuesFile(vf, values)) } func validateValuesFileExistence(valuesPath string) error { @@ -48,12 +60,19 @@ func validateValuesFileExistence(valuesPath string) error { return nil } -func validateValuesFile(valuesPath string) error { +func validateValuesFile(valuesPath string, overrides map[string]interface{}) error { values, err := chartutil.ReadValuesFile(valuesPath) if err != nil { return errors.Wrap(err, "unable to parse YAML") } + // Helm 3.0.0 carried over the values linting from Helm 2.x, which only tests the top + // level values against the top-level expectations. Subchart values are not linted. + // We could change that. For now, though, we retain that strategy, and thus can + // coalesce tables (like reuse-values does) instead of doing the full chart + // CoalesceValues. + values = chartutil.CoalesceTables(values, overrides) + ext := filepath.Ext(valuesPath) schemaPath := valuesPath[:len(valuesPath)-len(ext)] + ".schema.json" schema, err := ioutil.ReadFile(schemaPath) diff --git a/pkg/lint/rules/values_test.go b/pkg/lint/rules/values_test.go index 901a739fd..6d93d630e 100644 --- a/pkg/lint/rules/values_test.go +++ b/pkg/lint/rules/values_test.go @@ -17,15 +17,41 @@ limitations under the License. package rules import ( + "io/ioutil" "os" "path/filepath" "testing" -) -var ( - nonExistingValuesFilePath = filepath.Join("/fake/dir", "values.yaml") + "github.com/stretchr/testify/assert" + + "helm.sh/helm/v3/internal/test/ensure" ) +var nonExistingValuesFilePath = filepath.Join("/fake/dir", "values.yaml") + +const testSchema = ` +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "helm values test schema", + "type": "object", + "additionalProperties": false, + "required": [ + "username", + "password" + ], + "properties": { + "username": { + "description": "Your username", + "type": "string" + }, + "password": { + "description": "Your password", + "type": "string" + } + } +} +` + func TestValidateValuesYamlNotDirectory(t *testing.T) { _ = os.Mkdir(nonExistingValuesFilePath, os.ModePerm) defer os.Remove(nonExistingValuesFilePath) @@ -35,3 +61,68 @@ func TestValidateValuesYamlNotDirectory(t *testing.T) { t.Errorf("validateValuesFileExistence to return a linter error, got no error") } } + +func TestValidateValuesFileWellFormed(t *testing.T) { + badYaml := ` + not:well[]{}formed + ` + tmpdir := ensure.TempFile(t, "values.yaml", []byte(badYaml)) + defer os.RemoveAll(tmpdir) + valfile := filepath.Join(tmpdir, "values.yaml") + if err := validateValuesFile(valfile, map[string]interface{}{}); err == nil { + t.Fatal("expected values file to fail parsing") + } +} + +func TestValidateValuesFileSchema(t *testing.T) { + yaml := "username: admin\npassword: swordfish" + tmpdir := ensure.TempFile(t, "values.yaml", []byte(yaml)) + defer os.RemoveAll(tmpdir) + createTestingSchema(t, tmpdir) + + valfile := filepath.Join(tmpdir, "values.yaml") + if err := validateValuesFile(valfile, map[string]interface{}{}); err != nil { + t.Fatalf("Failed validation with %s", err) + } +} + +func TestValidateValuesFileSchemaFailure(t *testing.T) { + // 1234 is an int, not a string. This should fail. + yaml := "username: 1234\npassword: swordfish" + tmpdir := ensure.TempFile(t, "values.yaml", []byte(yaml)) + defer os.RemoveAll(tmpdir) + createTestingSchema(t, tmpdir) + + valfile := filepath.Join(tmpdir, "values.yaml") + + err := validateValuesFile(valfile, map[string]interface{}{}) + if err == nil { + t.Fatal("expected values file to fail parsing") + } + + assert.Contains(t, err.Error(), "Expected: string, given: integer", "integer should be caught by schema") +} + +func TestValidateValuesFileSchemaOverrides(t *testing.T) { + yaml := "username: admin" + overrides := map[string]interface{}{ + "password": "swordfish", + } + tmpdir := ensure.TempFile(t, "values.yaml", []byte(yaml)) + defer os.RemoveAll(tmpdir) + createTestingSchema(t, tmpdir) + + valfile := filepath.Join(tmpdir, "values.yaml") + if err := validateValuesFile(valfile, overrides); err != nil { + t.Fatalf("Failed validation with %s", err) + } +} + +func createTestingSchema(t *testing.T, dir string) string { + t.Helper() + schemafile := filepath.Join(dir, "values.schema.json") + if err := ioutil.WriteFile(schemafile, []byte(testSchema), 0700); err != nil { + t.Fatalf("Failed to write schema to tmpdir: %s", err) + } + return schemafile +} From bf12ae39344aef012927ab391eb26ddd3a30ae30 Mon Sep 17 00:00:00 2001 From: Niels de Vos Date: Wed, 13 May 2020 01:08:53 +0200 Subject: [PATCH 15/66] scripts: do not use optional 'which' command in get-helm installation (#8048) When installing Helm, the following warning gets printed on the console: Downloading https://get.helm.sh/helm-v2.16.6-linux-amd64.tar.gz Preparing to install helm and tiller into /usr/local/bin helm installed into /usr/local/bin/helm tiller installed into /usr/local/bin/tiller main: line 178: which: command not found Run 'helm init' to configure helm. The 'which' command is optional, and not always installed on all environments (like a Fedora container). Instead, use 'command -v' to detect if the executable is in the $PATH. Signed-off-by: Niels de Vos --- scripts/get | 2 +- scripts/get-helm-3 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/get b/scripts/get index afa02bbb1..094892346 100755 --- a/scripts/get +++ b/scripts/get @@ -175,7 +175,7 @@ fail_trap() { # testVersion tests the installed client to make sure it is working. testVersion() { set +e - HELM="$(which $PROJECT_NAME)" + HELM="$(command -v $PROJECT_NAME)" if [ "$?" = "1" ]; then echo "$PROJECT_NAME not found. Is $HELM_INSTALL_DIR on your "'$PATH?' exit 1 diff --git a/scripts/get-helm-3 b/scripts/get-helm-3 index 201065717..1d0b3502e 100755 --- a/scripts/get-helm-3 +++ b/scripts/get-helm-3 @@ -165,7 +165,7 @@ fail_trap() { # testVersion tests the installed client to make sure it is working. testVersion() { set +e - HELM="$(which $BINARY_NAME)" + HELM="$(command -v $BINARY_NAME)" if [ "$?" = "1" ]; then echo "$BINARY_NAME not found. Is $HELM_INSTALL_DIR on your "'$PATH?' exit 1 From 75aa425bfcfdffdbdd285a03fb0fceab8e28c778 Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Wed, 13 May 2020 08:36:47 -0700 Subject: [PATCH 16/66] bump to kubernetes 1.18.2 Signed-off-by: Matthew Fisher --- go.mod | 12 ++++++------ go.sum | 43 +++++++++++++++++-------------------------- 2 files changed, 23 insertions(+), 32 deletions(-) diff --git a/go.mod b/go.mod index 64ebfe307..f23d152a2 100644 --- a/go.mod +++ b/go.mod @@ -34,13 +34,13 @@ require ( github.com/stretchr/testify v1.5.1 github.com/xeipuuv/gojsonschema v1.1.0 golang.org/x/crypto v0.0.0-20200414173820-0848c9571904 - k8s.io/api v0.18.0 - k8s.io/apiextensions-apiserver v0.18.0 - k8s.io/apimachinery v0.18.0 - k8s.io/cli-runtime v0.18.0 - k8s.io/client-go v0.18.0 + k8s.io/api v0.18.2 + k8s.io/apiextensions-apiserver v0.18.2 + k8s.io/apimachinery v0.18.2 + k8s.io/cli-runtime v0.18.2 + k8s.io/client-go v0.18.2 k8s.io/klog v1.0.0 - k8s.io/kubectl v0.18.0 + k8s.io/kubectl v0.18.2 sigs.k8s.io/yaml v1.2.0 ) diff --git a/go.sum b/go.sum index 0a51a72e8..2908f3eb8 100644 --- a/go.sum +++ b/go.sum @@ -29,8 +29,6 @@ github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd h1:sjQovDkwrZp github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E= github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg= github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver/v3 v3.0.3 h1:znjIyLfpXEDQjOIEWh+ehwpTU14UzUPub3c3sm36u14= -github.com/Masterminds/semver/v3 v3.0.3/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/semver/v3 v3.1.0 h1:Y2lUDsFKVRSYGojLJ1yLxSXdMmMYTYls0rCvoqmMUQk= github.com/Masterminds/semver/v3 v3.1.0/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/sprig/v3 v3.1.0 h1:j7GpgZ7PdFqNsmncycTHsLmVPf5/3wJtlgW9TNDYD9Y= @@ -155,8 +153,6 @@ github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96 h1:cenwrSVm+Z7QL github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e h1:p1yVGRW3nmb85p1Sh1ZJSDm4A4iKLS5QNbvUHMgGu/M= -github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= @@ -321,13 +317,9 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huandu/xstrings v1.2.0 h1:yPeWdRnmynF7p+lLYz0H2tthW9lqhMJrQV/U7yy4wX0= -github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4= github.com/huandu/xstrings v1.3.1 h1:4jgBlKK6tLKFvO8u5pmYjG91cqytmDCDvGh7ECVFfFs= github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.7 h1:Y+UAYTZ7gDEuOfhxKWy+dvb5dRQ6rJjFSdX2HZY1/gI= -github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ= github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= @@ -587,7 +579,6 @@ golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d h1:9FCpayM9Egr1baVnV1SX0H87m+XB0B8S0hAMi99X/3U= golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947M/+gp0+CqQXDtMRC0fseo= @@ -737,20 +728,20 @@ gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -k8s.io/api v0.18.0 h1:lwYk8Vt7rsVTwjRU6pzEsa9YNhThbmbocQlKvNBB4EQ= -k8s.io/api v0.18.0/go.mod h1:q2HRQkfDzHMBZL9l/y9rH63PkQl4vae0xRT+8prbrK8= -k8s.io/apiextensions-apiserver v0.18.0 h1:HN4/P8vpGZFvB5SOMuPPH2Wt9Y/ryX+KRvIyAkchu1Q= -k8s.io/apiextensions-apiserver v0.18.0/go.mod h1:18Cwn1Xws4xnWQNC00FLq1E350b9lUF+aOdIWDOZxgo= -k8s.io/apimachinery v0.18.0 h1:fuPfYpk3cs1Okp/515pAf0dNhL66+8zk8RLbSX+EgAE= -k8s.io/apimachinery v0.18.0/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA= -k8s.io/apiserver v0.18.0/go.mod h1:3S2O6FeBBd6XTo0njUrLxiqk8GNy6wWOftjhJcXYnjw= -k8s.io/cli-runtime v0.18.0 h1:jG8XpSqQ5TrV0N+EZ3PFz6+gqlCk71dkggWCCq9Mq34= -k8s.io/cli-runtime v0.18.0/go.mod h1:1eXfmBsIJosjn9LjEBUd2WVPoPAY9XGTqTFcPMIBsUQ= -k8s.io/client-go v0.18.0 h1:yqKw4cTUQraZK3fcVCMeSa+lqKwcjZ5wtcOIPnxQno4= -k8s.io/client-go v0.18.0/go.mod h1:uQSYDYs4WhVZ9i6AIoEZuwUggLVEF64HOD37boKAtF8= -k8s.io/code-generator v0.18.0/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRVkTc= -k8s.io/component-base v0.18.0 h1:I+lP0fNfsEdTDpHaL61bCAqTZLoiWjEEP304Mo5ZQgE= -k8s.io/component-base v0.18.0/go.mod h1:u3BCg0z1uskkzrnAKFzulmYaEpZF7XC9Pf/uFyb1v2c= +k8s.io/api v0.18.2 h1:wG5g5ZmSVgm5B+eHMIbI9EGATS2L8Z72rda19RIEgY8= +k8s.io/api v0.18.2/go.mod h1:SJCWI7OLzhZSvbY7U8zwNl9UA4o1fizoug34OV/2r78= +k8s.io/apiextensions-apiserver v0.18.2 h1:I4v3/jAuQC+89L3Z7dDgAiN4EOjN6sbm6iBqQwHTah8= +k8s.io/apiextensions-apiserver v0.18.2/go.mod h1:q3faSnRGmYimiocj6cHQ1I3WpLqmDgJFlKL37fC4ZvY= +k8s.io/apimachinery v0.18.2 h1:44CmtbmkzVDAhCpRVSiP2R5PPrC2RtlIv/MoB8xpdRA= +k8s.io/apimachinery v0.18.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA= +k8s.io/apiserver v0.18.2/go.mod h1:Xbh066NqrZO8cbsoenCwyDJ1OSi8Ag8I2lezeHxzwzw= +k8s.io/cli-runtime v0.18.2 h1:JiTN5RgkFNTiMxHBRyrl6n26yKWAuNRlei1ZJALUmC8= +k8s.io/cli-runtime v0.18.2/go.mod h1:yfFR2sQQzDsV0VEKGZtrJwEy4hLZ2oj4ZIfodgxAHWQ= +k8s.io/client-go v0.18.2 h1:aLB0iaD4nmwh7arT2wIn+lMnAq7OswjaejkQ8p9bBYE= +k8s.io/client-go v0.18.2/go.mod h1:Xcm5wVGXX9HAA2JJ2sSBUn3tCJ+4SVlCbl2MNNv+CIU= +k8s.io/code-generator v0.18.2/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRVkTc= +k8s.io/component-base v0.18.2 h1:SJweNZAGcUvsypLGNPNGeJ9UgPZQ6+bW+gEHe8uyh/Y= +k8s.io/component-base v0.18.2/go.mod h1:kqLlMuhJNHQ9lz8Z7V5bxUUtjFZnrypArGl58gmDfUM= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= @@ -759,10 +750,10 @@ k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c h1:/KUFqjjqAcY4Us6luF5RDNZ16KJtb49HfR3ZHB9qYXM= k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= -k8s.io/kubectl v0.18.0 h1:hu52Ndq/d099YW+3sS3VARxFz61Wheiq8K9S7oa82Dk= -k8s.io/kubectl v0.18.0/go.mod h1:LOkWx9Z5DXMEg5KtOjHhRiC1fqJPLyCr3KtQgEolCkU= +k8s.io/kubectl v0.18.2 h1:9jnGSOC2DDVZmMUTMi0D1aed438mfQcgqa5TAzVjA1k= +k8s.io/kubectl v0.18.2/go.mod h1:OdgFa3AlsPKRpFFYE7ICTwulXOcMGXHTc+UKhHKvrb4= k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= -k8s.io/metrics v0.18.0/go.mod h1:8aYTW18koXqjLVKL7Ds05RPMX9ipJZI3mywYvBOxXd4= +k8s.io/metrics v0.18.2/go.mod h1:qga8E7QfYNR9Q89cSCAjinC9pTZ7yv1XSVGUB0vJypg= k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89 h1:d4vVOjXm687F1iLSP2q3lyPPuyvTUt3aVoBpi2DqRsU= k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0= From bfb39c0c68b989eea6a0b648f36aa5c7f930a515 Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Wed, 13 May 2020 11:10:47 -0700 Subject: [PATCH 17/66] bump DefaultCapabilities to 1.18 Signed-off-by: Matthew Fisher --- .../testdata/output/template-name-template.txt | 4 ++-- cmd/helm/testdata/output/template-set.txt | 4 ++-- .../output/template-show-only-multiple.txt | 4 ++-- .../testdata/output/template-show-only-one.txt | 4 ++-- cmd/helm/testdata/output/template-values-files.txt | 4 ++-- .../testdata/output/template-with-api-version.txt | 4 ++-- cmd/helm/testdata/output/template-with-crds.txt | 4 ++-- cmd/helm/testdata/output/template.txt | 4 ++-- pkg/chartutil/capabilities.go | 4 ++-- pkg/chartutil/capabilities_test.go | 14 +++++++------- 10 files changed, 25 insertions(+), 25 deletions(-) diff --git a/cmd/helm/testdata/output/template-name-template.txt b/cmd/helm/testdata/output/template-name-template.txt index 0130a2a92..24f2bb616 100644 --- a/cmd/helm/testdata/output/template-name-template.txt +++ b/cmd/helm/testdata/output/template-name-template.txt @@ -71,8 +71,8 @@ metadata: helm.sh/chart: "subchart1-0.1.0" app.kubernetes.io/instance: "foobar-YWJj-baz" kube-version/major: "1" - kube-version/minor: "16" - kube-version/version: "v1.16.0" + kube-version/minor: "18" + kube-version/version: "v1.18.0" spec: type: ClusterIP ports: diff --git a/cmd/helm/testdata/output/template-set.txt b/cmd/helm/testdata/output/template-set.txt index ddaa8886b..4c7f1f626 100644 --- a/cmd/helm/testdata/output/template-set.txt +++ b/cmd/helm/testdata/output/template-set.txt @@ -71,8 +71,8 @@ metadata: helm.sh/chart: "subchart1-0.1.0" app.kubernetes.io/instance: "RELEASE-NAME" kube-version/major: "1" - kube-version/minor: "16" - kube-version/version: "v1.16.0" + kube-version/minor: "18" + kube-version/version: "v1.18.0" spec: type: ClusterIP ports: diff --git a/cmd/helm/testdata/output/template-show-only-multiple.txt b/cmd/helm/testdata/output/template-show-only-multiple.txt index abb9a2e10..75b590e20 100644 --- a/cmd/helm/testdata/output/template-show-only-multiple.txt +++ b/cmd/helm/testdata/output/template-show-only-multiple.txt @@ -8,8 +8,8 @@ metadata: helm.sh/chart: "subchart1-0.1.0" app.kubernetes.io/instance: "RELEASE-NAME" kube-version/major: "1" - kube-version/minor: "16" - kube-version/version: "v1.16.0" + kube-version/minor: "18" + kube-version/version: "v1.18.0" kube-api-version/test: v1 spec: type: ClusterIP diff --git a/cmd/helm/testdata/output/template-show-only-one.txt b/cmd/helm/testdata/output/template-show-only-one.txt index f0dd0834e..ce61f481f 100644 --- a/cmd/helm/testdata/output/template-show-only-one.txt +++ b/cmd/helm/testdata/output/template-show-only-one.txt @@ -8,8 +8,8 @@ metadata: helm.sh/chart: "subchart1-0.1.0" app.kubernetes.io/instance: "RELEASE-NAME" kube-version/major: "1" - kube-version/minor: "16" - kube-version/version: "v1.16.0" + kube-version/minor: "18" + kube-version/version: "v1.18.0" kube-api-version/test: v1 spec: type: ClusterIP diff --git a/cmd/helm/testdata/output/template-values-files.txt b/cmd/helm/testdata/output/template-values-files.txt index ddaa8886b..4c7f1f626 100644 --- a/cmd/helm/testdata/output/template-values-files.txt +++ b/cmd/helm/testdata/output/template-values-files.txt @@ -71,8 +71,8 @@ metadata: helm.sh/chart: "subchart1-0.1.0" app.kubernetes.io/instance: "RELEASE-NAME" kube-version/major: "1" - kube-version/minor: "16" - kube-version/version: "v1.16.0" + kube-version/minor: "18" + kube-version/version: "v1.18.0" spec: type: ClusterIP ports: diff --git a/cmd/helm/testdata/output/template-with-api-version.txt b/cmd/helm/testdata/output/template-with-api-version.txt index 7a2a4d5bf..210dcc503 100644 --- a/cmd/helm/testdata/output/template-with-api-version.txt +++ b/cmd/helm/testdata/output/template-with-api-version.txt @@ -71,8 +71,8 @@ metadata: helm.sh/chart: "subchart1-0.1.0" app.kubernetes.io/instance: "RELEASE-NAME" kube-version/major: "1" - kube-version/minor: "16" - kube-version/version: "v1.16.0" + kube-version/minor: "18" + kube-version/version: "v1.18.0" kube-api-version/test: v1 spec: type: ClusterIP diff --git a/cmd/helm/testdata/output/template-with-crds.txt b/cmd/helm/testdata/output/template-with-crds.txt index b04a4d5d2..289eec291 100644 --- a/cmd/helm/testdata/output/template-with-crds.txt +++ b/cmd/helm/testdata/output/template-with-crds.txt @@ -87,8 +87,8 @@ metadata: helm.sh/chart: "subchart1-0.1.0" app.kubernetes.io/instance: "RELEASE-NAME" kube-version/major: "1" - kube-version/minor: "16" - kube-version/version: "v1.16.0" + kube-version/minor: "18" + kube-version/version: "v1.18.0" kube-api-version/test: v1 spec: type: ClusterIP diff --git a/cmd/helm/testdata/output/template.txt b/cmd/helm/testdata/output/template.txt index 8301c2231..82a21c5a1 100644 --- a/cmd/helm/testdata/output/template.txt +++ b/cmd/helm/testdata/output/template.txt @@ -71,8 +71,8 @@ metadata: helm.sh/chart: "subchart1-0.1.0" app.kubernetes.io/instance: "RELEASE-NAME" kube-version/major: "1" - kube-version/minor: "16" - kube-version/version: "v1.16.0" + kube-version/minor: "18" + kube-version/version: "v1.18.0" spec: type: ClusterIP ports: diff --git a/pkg/chartutil/capabilities.go b/pkg/chartutil/capabilities.go index f46350bb1..ce968c5d7 100644 --- a/pkg/chartutil/capabilities.go +++ b/pkg/chartutil/capabilities.go @@ -29,9 +29,9 @@ var ( // DefaultCapabilities is the default set of capabilities. DefaultCapabilities = &Capabilities{ KubeVersion: KubeVersion{ - Version: "v1.16.0", + Version: "v1.18.0", Major: "1", - Minor: "16", + Minor: "18", }, APIVersions: DefaultVersionSet, } diff --git a/pkg/chartutil/capabilities_test.go b/pkg/chartutil/capabilities_test.go index 3eeac76e2..416eea06d 100644 --- a/pkg/chartutil/capabilities_test.go +++ b/pkg/chartutil/capabilities_test.go @@ -42,19 +42,19 @@ func TestDefaultVersionSet(t *testing.T) { func TestDefaultCapabilities(t *testing.T) { kv := DefaultCapabilities.KubeVersion - if kv.String() != "v1.16.0" { - t.Errorf("Expected default KubeVersion.String() to be v1.16.0, got %q", kv.String()) + if kv.String() != "v1.18.0" { + t.Errorf("Expected default KubeVersion.String() to be v1.18.0, got %q", kv.String()) } - if kv.Version != "v1.16.0" { - t.Errorf("Expected default KubeVersion.Version to be v1.16.0, got %q", kv.Version) + if kv.Version != "v1.18.0" { + t.Errorf("Expected default KubeVersion.Version to be v1.18.0, got %q", kv.Version) } - if kv.GitVersion() != "v1.16.0" { - t.Errorf("Expected default KubeVersion.GitVersion() to be v1.16.0, got %q", kv.Version) + if kv.GitVersion() != "v1.18.0" { + t.Errorf("Expected default KubeVersion.GitVersion() to be v1.18.0, got %q", kv.Version) } if kv.Major != "1" { t.Errorf("Expected default KubeVersion.Major to be 1, got %q", kv.Major) } - if kv.Minor != "16" { + if kv.Minor != "18" { t.Errorf("Expected default KubeVersion.Minor to be 16, got %q", kv.Minor) } } From 2f39854d3f5da2f13cd749ccb08d61982cafef2f Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Wed, 13 May 2020 12:03:12 -0700 Subject: [PATCH 18/66] fix security mailing list address Signed-off-by: Matthew Fisher --- CONTRIBUTING.md | 206 +++++++++++++++++++++++++++--------------------- 1 file changed, 115 insertions(+), 91 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a637f9255..e27fa7d19 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,21 +1,22 @@ # Contributing Guidelines -The Helm project accepts contributions via GitHub pull requests. This document outlines the process to help get your contribution accepted. +The Helm project accepts contributions via GitHub pull requests. This document outlines the process +to help get your contribution accepted. ## Reporting a Security Issue -Most of the time, when you find a bug in Helm, it should be reported -using [GitHub issues](https://github.com/helm/helm/issues). However, if -you are reporting a _security vulnerability_, please email a report to -[cncf-kubernetes-helm-security@lists.cncf.io](mailto:cncf-kubernetes-helm-security@lists.cncf.io). This will give -us a chance to try to fix the issue before it is exploited in the wild. +Most of the time, when you find a bug in Helm, it should be reported using [GitHub +issues](https://github.com/helm/helm/issues). However, if you are reporting a _security +vulnerability_, please email a report to +[cncf-helm-security@lists.cncf.io](mailto:cncf-helm-security@lists.cncf.io). This will give us a +chance to try to fix the issue before it is exploited in the wild. ## Sign Your Work -The sign-off is a simple line at the end of the explanation for a commit. All -commits needs to be signed. Your signature certifies that you wrote the patch or -otherwise have the right to contribute the material. The rules are pretty simple, -if you can certify the below (from [developercertificate.org](https://developercertificate.org/)): +The sign-off is a simple line at the end of the explanation for a commit. All commits needs to be +signed. Your signature certifies that you wrote the patch or otherwise have the right to contribute +the material. The rules are pretty simple, if you can certify the below (from +[developercertificate.org](https://developercertificate.org/)): ``` Developer Certificate of Origin @@ -62,11 +63,11 @@ Then you just add a line to every git commit message: Use your real name (sorry, no pseudonyms or anonymous contributions.) -If you set your `user.name` and `user.email` git configs, you can sign your -commit automatically with `git commit -s`. +If you set your `user.name` and `user.email` git configs, you can sign your commit automatically +with `git commit -s`. -Note: If your git config information is set properly then viewing the - `git log` information for your commit will look something like this: +Note: If your git config information is set properly then viewing the `git log` information for your + commit will look something like this: ``` Author: Joe Smith @@ -77,8 +78,8 @@ Date: Thu Feb 2 11:41:15 2018 -0800 Signed-off-by: Joe Smith ``` -Notice the `Author` and `Signed-off-by` lines match. If they don't -your PR will be rejected by the automated DCO check. +Notice the `Author` and `Signed-off-by` lines match. If they don't your PR will be rejected by the +automated DCO check. ## Support Channels @@ -89,49 +90,69 @@ Whether you are a user or contributor, official support channels include: - User: [#helm-users](https://kubernetes.slack.com/messages/C0NH30761/details/) - Contributor: [#helm-dev](https://kubernetes.slack.com/messages/C51E88VDG/) -Before opening a new issue or submitting a new pull request, it's helpful to search the project - it's likely that another user has already reported the issue you're facing, or it's a known issue that we're already aware of. It is also worth asking on the Slack channels. +Before opening a new issue or submitting a new pull request, it's helpful to search the project - +it's likely that another user has already reported the issue you're facing, or it's a known issue +that we're already aware of. It is also worth asking on the Slack channels. ## Milestones -We use milestones to track progress of releases. There are also 2 special milestones -used for helping us keep work organized: `Upcoming - Minor` and `Upcoming - Major` +We use milestones to track progress of releases. There are also 2 special milestones used for +helping us keep work organized: `Upcoming - Minor` and `Upcoming - Major` -`Upcoming - Minor` is used for keeping track of issues that aren't assigned to a specific -release but could easily be addressed in a minor release. `Upcoming - Major` keeps track -of issues that will need to be addressed in a major release. For example, if the current -version is `3.2.0` an issue/PR could fall in to one of 4 different active milestones: -`3.2.1`, `3.3.0`, `Upcoming - Minor`, or `Upcoming - Major`. If an issue pertains to a -specific upcoming bug or minor release, it would go into `3.2.1` or `3.3.0`. If the issue/PR -does not have a specific milestone yet, but it is likely that it will land in a `3.X` release, -it should go into `Upcoming - Minor`. If the issue/PR is a large functionality add or change -and/or it breaks compatibility, then it should be added to the `Upcoming - Major` milestone. -An issue that we are not sure we will be doing will not be added to any milestone. +`Upcoming - Minor` is used for keeping track of issues that aren't assigned to a specific release +but could easily be addressed in a minor release. `Upcoming - Major` keeps track of issues that will +need to be addressed in a major release. For example, if the current version is `3.2.0` an issue/PR +could fall in to one of 4 different active milestones: `3.2.1`, `3.3.0`, `Upcoming - Minor`, or +`Upcoming - Major`. If an issue pertains to a specific upcoming bug or minor release, it would go +into `3.2.1` or `3.3.0`. If the issue/PR does not have a specific milestone yet, but it is likely +that it will land in a `3.X` release, it should go into `Upcoming - Minor`. If the issue/PR is a +large functionality add or change and/or it breaks compatibility, then it should be added to the +`Upcoming - Major` milestone. An issue that we are not sure we will be doing will not be added to +any milestone. -A milestone (and hence release) is considered done when all outstanding issues/PRs have been closed or moved to another milestone. +A milestone (and hence release) is considered done when all outstanding issues/PRs have been closed +or moved to another milestone. ## Semantic Versioning -Helm maintains a strong commitment to backward compatibility. All of our changes to protocols and formats are backward compatible from one major release to the next. No features, flags, or commands are removed or substantially modified (unless we need to fix a security issue). +Helm maintains a strong commitment to backward compatibility. All of our changes to protocols and +formats are backward compatible from one major release to the next. No features, flags, or commands +are removed or substantially modified (unless we need to fix a security issue). -We also try very hard to not change publicly accessible Go library definitions inside of the `pkg/` directory of our source code. +We also try very hard to not change publicly accessible Go library definitions inside of the `pkg/` +directory of our source code. For a quick summary of our backward compatibility guidelines for releases between 3.0 and 4.0: - Command line commands, flags, and arguments MUST be backward compatible - File formats (such as Chart.yaml) MUST be backward compatible -- Any chart that worked on a previous version of Helm 3 MUST work on a new version of Helm 3 (barring the cases where (a) Kubernetes itself changed, and (b) the chart worked because it exploited a bug) +- Any chart that worked on a previous version of Helm 3 MUST work on a new version of Helm 3 + (barring the cases where (a) Kubernetes itself changed, and (b) the chart worked because it + exploited a bug) - Chart repository functionality MUST be backward compatible -- Go libraries inside of `pkg/` SHOULD remain backward compatible, though code inside of `cmd/` and `internal/` may be changed from release to release without notice. +- Go libraries inside of `pkg/` SHOULD remain backward compatible, though code inside of `cmd/` and + `internal/` may be changed from release to release without notice. ## Support Contract for Helm 2 -With Helm 2's current release schedule, we want to take into account any migration issues for users due to the upcoming holiday shopping season and tax season. We also want to clarify what actions may occur after the support contract ends for Helm 2, so that users will not be surprised or caught off guard. +With Helm 2's current release schedule, we want to take into account any migration issues for users +due to the upcoming holiday shopping season and tax season. We also want to clarify what actions may +occur after the support contract ends for Helm 2, so that users will not be surprised or caught off +guard. -After Helm 2.15.0 is released, Helm 2 will go into "maintenance mode". We will continue to accept bug fixes and fix any security issues that arise, but no new features will be accepted for Helm 2. All feature development will be moved over to Helm 3. +After Helm 2.15.0 is released, Helm 2 will go into "maintenance mode". We will continue to accept +bug fixes and fix any security issues that arise, but no new features will be accepted for Helm 2. +All feature development will be moved over to Helm 3. -6 months after Helm 3.0.0's public release, Helm 2 will stop accepting bug fixes. Only security issues will be accepted. +6 months after Helm 3.0.0's public release, Helm 2 will stop accepting bug fixes. Only security +issues will be accepted. -12 months after Helm 3.0.0's public release, support for Helm 2 will formally end. Download links for the Helm 2 client through Google Cloud Storage, the Docker image for Tiller stored in Google Container Registry, and the Google Cloud buckets for the stable and incubator chart repositories may no longer work at any point. Client downloads through `get.helm.sh` will continue to work, and we will distribute a Tiller image that will be made available at an alternative location which can be updated with `helm init --tiller-image`. +12 months after Helm 3.0.0's public release, support for Helm 2 will formally end. Download links +for the Helm 2 client through Google Cloud Storage, the Docker image for Tiller stored in Google +Container Registry, and the Google Cloud buckets for the stable and incubator chart repositories may +no longer work at any point. Client downloads through `get.helm.sh` will continue to work, and we +will distribute a Tiller image that will be made available at an alternative location which can be +updated with `helm init --tiller-image`. ## Issues @@ -141,45 +162,46 @@ Issues are used as the primary method for tracking anything to do with the Helm There are 5 types of issues (each with their own corresponding [label](#labels)): -- `question/support`: These are support or functionality inquiries that we want to have a record of for -future reference. Generally these are questions that are too complex or large to store in the -Slack channel or have particular interest to the community as a whole. Depending on the discussion, -these can turn into `feature` or `bug` issues. +- `question/support`: These are support or functionality inquiries that we want to have a record of + for future reference. Generally these are questions that are too complex or large to store in the + Slack channel or have particular interest to the community as a whole. Depending on the + discussion, these can turn into `feature` or `bug` issues. - `proposal`: Used for items (like this one) that propose a new ideas or functionality that require -a larger community discussion. This allows for feedback from others in the community before a -feature is actually developed. This is not needed for small additions. Final word on whether or -not a feature needs a proposal is up to the core maintainers. All issues that are proposals should -both have a label and an issue title of "Proposal: [the rest of the title]." A proposal can become -a `feature` and does not require a milestone. -- `feature`: These track specific feature requests and ideas until they are complete. They can evolve -from a `proposal` or can be submitted individually depending on the size. + a larger community discussion. This allows for feedback from others in the community before a + feature is actually developed. This is not needed for small additions. Final word on whether or + not a feature needs a proposal is up to the core maintainers. All issues that are proposals should + both have a label and an issue title of "Proposal: [the rest of the title]." A proposal can become + a `feature` and does not require a milestone. +- `feature`: These track specific feature requests and ideas until they are complete. They can + evolve from a `proposal` or can be submitted individually depending on the size. - `bug`: These track bugs with the code - `docs`: These track problems with the documentation (i.e. missing or incomplete) ### Issue Lifecycle The issue lifecycle is mainly driven by the core maintainers, but is good information for those -contributing to Helm. All issue types follow the same general lifecycle. Differences are noted below. +contributing to Helm. All issue types follow the same general lifecycle. Differences are noted +below. 1. Issue creation 2. Triage - - The maintainer in charge of triaging will apply the proper labels for the issue. This - includes labels for priority, type, and metadata (such as `good first issue`). The only issue - priority we will be tracking is whether or not the issue is "critical." If additional - levels are needed in the future, we will add them. - - (If needed) Clean up the title to succinctly and clearly state the issue. Also ensure - that proposals are prefaced with "Proposal: [the rest of the title]". - - Add the issue to the correct milestone. If any questions come up, don't worry about - adding the issue to a milestone until the questions are answered. + - The maintainer in charge of triaging will apply the proper labels for the issue. This includes + labels for priority, type, and metadata (such as `good first issue`). The only issue priority + we will be tracking is whether or not the issue is "critical." If additional levels are needed + in the future, we will add them. + - (If needed) Clean up the title to succinctly and clearly state the issue. Also ensure that + proposals are prefaced with "Proposal: [the rest of the title]". + - Add the issue to the correct milestone. If any questions come up, don't worry about adding the + issue to a milestone until the questions are answered. - We attempt to do this process at least once per work day. 3. Discussion - issues that are labeled as `feature` or `bug` should be connected to the PR that resolves it. - - Whoever is working on a `feature` or `bug` issue (whether a maintainer or someone from - the community), should either assign the issue to themself or make a comment in the issue - saying that they are taking it. - - `proposal` and `support/question` issues should stay open until resolved or if they have not been - active for more than 30 days. This will help keep the issue queue to a manageable size and - reduce noise. Should the issue need to stay open, the `keep open` label can be added. + - Whoever is working on a `feature` or `bug` issue (whether a maintainer or someone from the + community), should either assign the issue to themself or make a comment in the issue saying + that they are taking it. + - `proposal` and `support/question` issues should stay open until resolved or if they have not + been active for more than 30 days. This will help keep the issue queue to a manageable size + and reduce noise. Should the issue need to stay open, the `keep open` label can be added. 4. Issue closure ## How to Contribute a Patch @@ -188,7 +210,8 @@ contributing to Helm. All issue types follow the same general lifecycle. Differe 2. Fork the desired repo; develop and test your code changes. 3. Submit a pull request, making sure to sign your work and link the related issue. -Coding conventions and standards are explained in the [official developer docs](https://helm.sh/docs/developers/). +Coding conventions and standards are explained in the [official developer +docs](https://helm.sh/docs/developers/). ## Pull Requests @@ -199,41 +222,42 @@ Like any good open source project, we use Pull Requests (PRs) to track code chan 1. PR creation - PRs are usually created to fix or else be a subset of other PRs that fix a particular issue. - We more than welcome PRs that are currently in progress. They are a great way to keep track of - important work that is in-flight, but useful for others to see. If a PR is a work in progress, - it **must** be prefaced with "WIP: [title]". Once the PR is ready for review, remove "WIP" from - the title. + important work that is in-flight, but useful for others to see. If a PR is a work in progress, + it **must** be prefaced with "WIP: [title]". Once the PR is ready for review, remove "WIP" + from the title. - It is preferred, but not required, to have a PR tied to a specific issue. There can be - circumstances where if it is a quick fix then an issue might be overkill. The details provided - in the PR description would suffice in this case. + circumstances where if it is a quick fix then an issue might be overkill. The details provided + in the PR description would suffice in this case. 2. Triage - The maintainer in charge of triaging will apply the proper labels for the issue. This should - include at least a size label, `bug` or `feature`, and `awaiting review` once all labels are applied. - See the [Labels section](#labels) for full details on the definitions of labels. + include at least a size label, `bug` or `feature`, and `awaiting review` once all labels are + applied. See the [Labels section](#labels) for full details on the definitions of labels. - Add the PR to the correct milestone. This should be the same as the issue the PR closes. 3. Assigning reviews - - Once a review has the `awaiting review` label, maintainers will review them as schedule permits. - The maintainer who takes the issue should self-request a review. - - Any PR with the `size/large` label requires 2 review approvals from maintainers before it can be - merged. Those with `size/medium` or `size/small` are per the judgement of the maintainers. + - Once a review has the `awaiting review` label, maintainers will review them as schedule + permits. The maintainer who takes the issue should self-request a review. + - Any PR with the `size/large` label requires 2 review approvals from maintainers before it can + be merged. Those with `size/medium` or `size/small` are per the judgement of the maintainers. 4. Reviewing/Discussion - All reviews will be completed using Github review tool. - A "Comment" review should be used when there are questions about the code that should be - answered, but that don't involve code changes. This type of review does not count as approval. - - A "Changes Requested" review indicates that changes to the code need to be made before they will be merged. + answered, but that don't involve code changes. This type of review does not count as approval. + - A "Changes Requested" review indicates that changes to the code need to be made before they + will be merged. - Reviewers should update labels as needed (such as `needs rebase`) 5. Address comments by answering questions or changing code 6. LGTM (Looks good to me) - - Once a Reviewer has completed a review and the code looks ready to merge, an "Approve" review is used - to signal to the contributor and to other maintainers that you have reviewed the code and feel that it is - ready to be merged. + - Once a Reviewer has completed a review and the code looks ready to merge, an "Approve" review + is used to signal to the contributor and to other maintainers that you have reviewed the code + and feel that it is ready to be merged. 7. Merge or close - - PRs should stay open until merged or if they have not been active for more than 30 days. - This will help keep the PR queue to a manageable size and reduce noise. Should the PR need - to stay open (like in the case of a WIP), the `keep open` label can be added. + - PRs should stay open until merged or if they have not been active for more than 30 days. This + will help keep the PR queue to a manageable size and reduce noise. Should the PR need to stay + open (like in the case of a WIP), the `keep open` label can be added. - Before merging a PR, refer to the topic on [Size Labels](#size-labels) below to determine if the PR requires more than one LGTM to merge. - If the owner of the PR is listed in the `OWNERS` file, that user **must** merge their own PRs - or explicitly request another OWNER do that for them. + or explicitly request another OWNER do that for them. - If the owner of a PR is _not_ listed in `OWNERS`, any core maintainer may merge the PR. #### Documentation PRs @@ -286,12 +310,12 @@ The following tables define all label types used for Helm. It is split up by cat #### Size labels -Size labels are used to indicate how "dangerous" a PR is. The guidelines below are used to assign the -labels, but ultimately this can be changed by the maintainers. For example, even if a PR only makes -30 lines of changes in 1 file, but it changes key functionality, it will likely be labeled as `size/L` -because it requires sign off from multiple people. Conversely, a PR that adds a small feature, but requires -another 150 lines of tests to cover all cases, could be labeled as `size/S` even though the number of -lines is greater than defined below. +Size labels are used to indicate how "dangerous" a PR is. The guidelines below are used to assign +the labels, but ultimately this can be changed by the maintainers. For example, even if a PR only +makes 30 lines of changes in 1 file, but it changes key functionality, it will likely be labeled as +`size/L` because it requires sign off from multiple people. Conversely, a PR that adds a small +feature, but requires another 150 lines of tests to cover all cases, could be labeled as `size/S` +even though the number of lines is greater than defined below. PRs submitted by a core maintainer, regardless of size, only requires approval from one additional maintainer. This ensures there are at least two maintainers who are aware of any significant PRs From ae738d7d87bbd5db7203db7441fb11e32b02df40 Mon Sep 17 00:00:00 2001 From: Hidde Beydals Date: Wed, 13 May 2020 23:51:32 +0200 Subject: [PATCH 19/66] feat(getter): add timeout option (#7950) To allow finer grain control over the request when utilizing `getter` as a package. Signed-off-by: Hidde Beydals --- pkg/getter/getter.go | 9 +++++++++ pkg/getter/httpgetter.go | 1 + pkg/getter/httpgetter_test.go | 7 +++++++ 3 files changed, 17 insertions(+) diff --git a/pkg/getter/getter.go b/pkg/getter/getter.go index 4ccc74834..8ee08cb7f 100644 --- a/pkg/getter/getter.go +++ b/pkg/getter/getter.go @@ -18,6 +18,7 @@ package getter import ( "bytes" + "time" "github.com/pkg/errors" @@ -36,6 +37,7 @@ type options struct { username string password string userAgent string + timeout time.Duration } // Option allows specifying various settings configurable by the user for overriding the defaults @@ -81,6 +83,13 @@ func WithTLSClientConfig(certFile, keyFile, caFile string) Option { } } +// WithTimeout sets the timeout for requests +func WithTimeout(timeout time.Duration) Option { + return func(opts *options) { + opts.timeout = timeout + } +} + // Getter is an interface to support GET to the specified URL. type Getter interface { // Get file content by url string diff --git a/pkg/getter/httpgetter.go b/pkg/getter/httpgetter.go index 46c817a9c..858af91ac 100644 --- a/pkg/getter/httpgetter.go +++ b/pkg/getter/httpgetter.go @@ -119,6 +119,7 @@ func (g *HTTPGetter) httpClient() (*http.Client, error) { client := &http.Client{ Transport: transport, + Timeout: g.opts.timeout, } return client, nil diff --git a/pkg/getter/httpgetter_test.go b/pkg/getter/httpgetter_test.go index 0e157eccd..7973b5f85 100644 --- a/pkg/getter/httpgetter_test.go +++ b/pkg/getter/httpgetter_test.go @@ -26,6 +26,7 @@ import ( "strconv" "strings" "testing" + "time" "github.com/pkg/errors" @@ -48,6 +49,7 @@ func TestHTTPGetter(t *testing.T) { join := filepath.Join ca, pub, priv := join(cd, "rootca.crt"), join(cd, "crt.pem"), join(cd, "key.pem") insecure := false + timeout := time.Second * 5 // Test with options g, err = NewHTTPGetter( @@ -55,6 +57,7 @@ func TestHTTPGetter(t *testing.T) { WithUserAgent("Groot"), WithTLSClientConfig(pub, priv, ca), WithInsecureSkipVerifyTLS(insecure), + WithTimeout(timeout), ) if err != nil { t.Fatal(err) @@ -93,6 +96,10 @@ func TestHTTPGetter(t *testing.T) { t.Errorf("Expected NewHTTPGetter to contain %t as InsecureSkipVerifyTLs flag, got %t", false, hg.opts.insecureSkipVerifyTLS) } + if hg.opts.timeout != timeout { + t.Errorf("Expected NewHTTPGetter to contain %s as Timeout flag, got %s", timeout, hg.opts.timeout) + } + // Test if setting insecureSkipVerifyTLS is being passed to the ops insecure = true From decab8ea2e6ea4b31560aff50abb2676a67ec8ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E6=98=8E=E5=90=8C=E5=AD=A6?= <11614773+liuming-dev@users.noreply.github.com> Date: Thu, 14 May 2020 05:53:37 +0800 Subject: [PATCH 20/66] fix: upgrade using --force shoud not run patch logic (#8000) fix helm/helm#7999 Signed-off-by: Liu Ming --- pkg/kube/client.go | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/pkg/kube/client.go b/pkg/kube/client.go index c1de2b299..4683d8033 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -418,29 +418,29 @@ func updateResource(c *Client, target *resource.Info, currentObj runtime.Object, kind = target.Mapping.GroupVersionKind.Kind ) - patch, patchType, err := createPatch(target, currentObj) - if err != nil { - return errors.Wrap(err, "failed to create patch") - } - - if patch == nil || string(patch) == "{}" { - c.Log("Looks like there are no changes for %s %q", target.Mapping.GroupVersionKind.Kind, target.Name) - // This needs to happen to make sure that tiller has the latest info from the API - // Otherwise there will be no labels and other functions that use labels will panic - if err := target.Get(); err != nil { - return errors.Wrap(err, "failed to refresh resource information") - } - return nil - } - // if --force is applied, attempt to replace the existing resource with the new object. if force { + var err error obj, err = helper.Replace(target.Namespace, target.Name, true, target.Object) if err != nil { return errors.Wrap(err, "failed to replace object") } c.Log("Replaced %q with kind %s for kind %s", target.Name, currentObj.GetObjectKind().GroupVersionKind().Kind, kind) } else { + patch, patchType, err := createPatch(target, currentObj) + if err != nil { + return errors.Wrap(err, "failed to create patch") + } + + if patch == nil || string(patch) == "{}" { + c.Log("Looks like there are no changes for %s %q", target.Mapping.GroupVersionKind.Kind, target.Name) + // This needs to happen to make sure that tiller has the latest info from the API + // Otherwise there will be no labels and other functions that use labels will panic + if err := target.Get(); err != nil { + return errors.Wrap(err, "failed to refresh resource information") + } + return nil + } // send patch to server obj, err = helper.Patch(target.Namespace, target.Name, patchType, patch, nil) if err != nil { From 512544b9abbc75418348b76037fee3156ea1d3bd Mon Sep 17 00:00:00 2001 From: Matt Farina Date: Wed, 13 May 2020 18:09:27 -0400 Subject: [PATCH 21/66] Fixing PAX Header handling (#8086) * Fixing issue with PAX headers in plugin archive PAX Headers can be added by some systems that create archives. Helm should ignore them when extracting. There are two PAX headers. One is global and the other is not. Both are ignored. The test adds only the PAX global header because the Go tar package is unable to write the header that is not global. Closes #8084 Signed-off-by: Matt Farina * Removing the PAX header test as it is not working The PAX header test was making a WriteHeader call and ignoring the error. When writing the type TypeXHeader it was causing an error that was being silently ignored. The Go tar package cannot write this type and produces an error when one tries to. The error reads "cannot manually encode TypeXHeader, TypeGNULongName, or TypeGNULongLink headers" Signed-off-by: Matt Farina * Adding check of returned error in test Adding a check for the returned error to make sure a non-nil value is not returned. Signed-off-by: Matt Farina --- pkg/chart/loader/archive_test.go | 34 +++++---------------- pkg/plugin/installer/http_installer.go | 3 ++ pkg/plugin/installer/http_installer_test.go | 13 ++++++++ 3 files changed, 23 insertions(+), 27 deletions(-) diff --git a/pkg/chart/loader/archive_test.go b/pkg/chart/loader/archive_test.go index 7d8c8b51e..41b0af1aa 100644 --- a/pkg/chart/loader/archive_test.go +++ b/pkg/chart/loader/archive_test.go @@ -43,46 +43,26 @@ func TestLoadArchiveFiles(t *testing.T) { generate: func(w *tar.Writer) { // simulate the presence of a `pax_global_header` file like you would get when // processing a GitHub release archive. - _ = w.WriteHeader(&tar.Header{ + err := w.WriteHeader(&tar.Header{ Typeflag: tar.TypeXGlobalHeader, Name: "pax_global_header", }) - - // we need to have at least one file, otherwise we'll get the "no files in chart archive" error - _ = w.WriteHeader(&tar.Header{ - Typeflag: tar.TypeReg, - Name: "dir/empty", - }) - }, - check: func(t *testing.T, files []*BufferedFile, err error) { if err != nil { - t.Fatalf(`got unwanted error [%#v] for tar file with pax_global_header content`, err) + t.Fatal(err) } - if len(files) != 1 { - t.Fatalf(`expected to get one file but got [%v]`, files) - } - }, - }, - { - name: "should ignore files with TypeXHeader type", - generate: func(w *tar.Writer) { - // simulate the presence of a `pax_header` file like you might get when - // processing a GitHub release archive. - _ = w.WriteHeader(&tar.Header{ - Typeflag: tar.TypeXHeader, - Name: "pax_header", - }) - // we need to have at least one file, otherwise we'll get the "no files in chart archive" error - _ = w.WriteHeader(&tar.Header{ + err = w.WriteHeader(&tar.Header{ Typeflag: tar.TypeReg, Name: "dir/empty", }) + if err != nil { + t.Fatal(err) + } }, check: func(t *testing.T, files []*BufferedFile, err error) { if err != nil { - t.Fatalf(`got unwanted error [%#v] for tar file with pax_header content`, err) + t.Fatalf(`got unwanted error [%#v] for tar file with pax_global_header content`, err) } if len(files) != 1 { diff --git a/pkg/plugin/installer/http_installer.go b/pkg/plugin/installer/http_installer.go index 629bbec39..c07cad80a 100644 --- a/pkg/plugin/installer/http_installer.go +++ b/pkg/plugin/installer/http_installer.go @@ -188,6 +188,9 @@ func (g *TarGzExtractor) Extract(buffer *bytes.Buffer, targetDir string) error { return err } outFile.Close() + // We don't want to process these extension header files. + case tar.TypeXGlobalHeader, tar.TypeXHeader: + continue default: return errors.Errorf("unknown type: %b in %s", header.Typeflag, header.Name) } diff --git a/pkg/plugin/installer/http_installer_test.go b/pkg/plugin/installer/http_installer_test.go index b496a1b01..99470ace6 100644 --- a/pkg/plugin/installer/http_installer_test.go +++ b/pkg/plugin/installer/http_installer_test.go @@ -222,6 +222,19 @@ func TestExtract(t *testing.T) { t.Fatal(err) } } + + // Add pax global headers. This should be ignored. + // Note the PAX header that isn't global cannot be written using WriteHeader. + // Details are in the internal Go function for the tar packaged named + // allowedFormats. For a TypeXHeader it will return a message stating + // "cannot manually encode TypeXHeader, TypeGNULongName, or TypeGNULongLink headers" + if err := tw.WriteHeader(&tar.Header{ + Name: "pax_global_header", + Typeflag: tar.TypeXGlobalHeader, + }); err != nil { + t.Fatal(err) + } + if err := tw.Close(); err != nil { t.Fatal(err) } From b18e7e201e55ba38fdecbcf81e4da512e55444b4 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Thu, 14 May 2020 08:06:18 -0400 Subject: [PATCH 22/66] chore(*): Fix formatting Signed-off-by: Marc Khouzam --- pkg/getter/httpgetter.go | 2 +- pkg/getter/httpgetter_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/getter/httpgetter.go b/pkg/getter/httpgetter.go index 858af91ac..c100b2cc0 100644 --- a/pkg/getter/httpgetter.go +++ b/pkg/getter/httpgetter.go @@ -92,7 +92,7 @@ func NewHTTPGetter(options ...Option) (Getter, error) { func (g *HTTPGetter) httpClient() (*http.Client, error) { transport := &http.Transport{ DisableCompression: true, - Proxy: http.ProxyFromEnvironment, + Proxy: http.ProxyFromEnvironment, } if (g.opts.certFile != "" && g.opts.keyFile != "") || g.opts.caFile != "" { tlsConf, err := tlsutil.NewClientTLS(g.opts.certFile, g.opts.keyFile, g.opts.caFile) diff --git a/pkg/getter/httpgetter_test.go b/pkg/getter/httpgetter_test.go index 7973b5f85..90578f7b7 100644 --- a/pkg/getter/httpgetter_test.go +++ b/pkg/getter/httpgetter_test.go @@ -293,4 +293,4 @@ func TestHTTPGetterTarDownload(t *testing.T) { if mimeType != expectedMimeType { t.Fatalf("Expected response with MIME type %s, but got %s", expectedMimeType, mimeType) } -} \ No newline at end of file +} From 88f6991ffff04c48dd8fd257d238aca48aef80df Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Thu, 14 May 2020 15:00:41 -0400 Subject: [PATCH 23/66] feat(test): Update golangci-lint to 1.27.0 Since we've moved to Go 1.14, golangci-lint has been silently failing. This commit updates to a compatible version. Signed-off-by: Marc Khouzam --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index e6ce2e242..bf3b78179 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -9,7 +9,7 @@ jobs: environment: GOCACHE: "/tmp/go/cache" - GOLANGCI_LINT_VERSION: "1.21.0" + GOLANGCI_LINT_VERSION: "1.27.0" steps: - checkout From 0366f9970f0ff5c0b61b02521d139445bfaeba8f Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Fri, 10 Apr 2020 11:47:31 -0400 Subject: [PATCH 24/66] fix(comp): Prepare plugin completion for Cobra 1.0 Cobra 1.0.0 introduces support for Custom Go Completions. However, there is a small difference compared to helm's existing solution. The difference is that Cobra will not complete sub-commands if there are any dynamic completion functions registered. The way helm implemented plugin completions had the dynamic completion function associated with the root plugin command (e.g. 2to3); with Cobra, this prevents any of the sub-commands of the plugin to be completed (i.e., 2to3 will not show the static sub-commands). The solution is to only register the dynamic completion function for a plugin command that doesn't have any further sub-commands. This allows all sub-commands to be completed properly, and when there are no more levels of sub-commands, the dynamic completion is called. This commit had to make two changes to achieve this: 1- refactor the load_plugins.go file to extract the logic to call the plugin.complete executable (for dynamic completions), so that it could be added to each final sub-command. 2- load the static completion not only for the "completion" command like before, but also for the "__complete" command, so that when the __complete command is called for dynamic completion of a sub-command, it is aware of the sub-command in question. The second change is also valuable for the future support of completion for the Fish shell. Completion for the fish shell uses the __complete command not only for dynamic completions but also for basic command and flag completion. This implies that the __complete command must be aware of the plugins sub-commands, and therefore that the plugin's static completion be loaded. Signed-off-by: Marc Khouzam --- cmd/helm/load_plugins.go | 263 +++++++++++++++++++++------------------ 1 file changed, 142 insertions(+), 121 deletions(-) diff --git a/cmd/helm/load_plugins.go b/cmd/helm/load_plugins.go index a23a067fb..36de50135 100644 --- a/cmd/helm/load_plugins.go +++ b/cmd/helm/load_plugins.go @@ -64,21 +64,6 @@ func loadPlugins(baseCmd *cobra.Command, out io.Writer) { return } - processParent := func(cmd *cobra.Command, args []string) ([]string, error) { - k, u := manuallyProcessArgs(args) - if err := cmd.Parent().ParseFlags(k); err != nil { - return nil, err - } - return u, nil - } - - // If we are dealing with the completion command, we try to load more details about the plugins - // if available, so as to allow for command and flag completion - if subCmd, _, err := baseCmd.Find(os.Args[1:]); err == nil && subCmd.Name() == "completion" { - loadPluginsForCompletion(baseCmd, found) - return - } - // Now we create commands for all of these. for _, plug := range found { plug := plug @@ -87,33 +72,6 @@ func loadPlugins(baseCmd *cobra.Command, out io.Writer) { md.Usage = fmt.Sprintf("the %q plugin", md.Name) } - // This function is used to setup the environment for the plugin and then - // call the executable specified by the parameter 'main' - callPluginExecutable := func(cmd *cobra.Command, main string, argv []string, out io.Writer) error { - env := os.Environ() - for k, v := range settings.EnvVars() { - env = append(env, fmt.Sprintf("%s=%s", k, v)) - } - - prog := exec.Command(main, argv...) - prog.Env = env - prog.Stdin = os.Stdin - prog.Stdout = out - prog.Stderr = os.Stderr - if err := prog.Run(); err != nil { - if eerr, ok := err.(*exec.ExitError); ok { - os.Stderr.Write(eerr.Stderr) - status := eerr.Sys().(syscall.WaitStatus) - return pluginError{ - error: errors.Errorf("plugin %q exited with error", md.Name), - code: status.ExitStatus(), - } - } - return err - } - return nil - } - c := &cobra.Command{ Use: md.Name, Short: md.Usage, @@ -134,62 +92,59 @@ func loadPlugins(baseCmd *cobra.Command, out io.Writer) { return errors.Errorf("plugin %q exited with error", md.Name) } - return callPluginExecutable(cmd, main, argv, out) + return callPluginExecutable(md.Name, main, argv, out) }, // This passes all the flags to the subcommand. DisableFlagParsing: true, } + // TODO: Make sure a command with this name does not already exist. + baseCmd.AddCommand(c) - // Setup dynamic completion for the plugin - completion.RegisterValidArgsFunc(c, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { - u, err := processParent(cmd, args) - if err != nil { - return nil, completion.BashCompDirectiveError - } - - // We will call the dynamic completion script of the plugin - main := strings.Join([]string{plug.Dir, pluginDynamicCompletionExecutable}, string(filepath.Separator)) - - argv := []string{} - if !md.IgnoreFlags { - argv = append(argv, u...) - argv = append(argv, toComplete) - } - plugin.SetupPluginEnv(settings, md.Name, plug.Dir) + // For completion, we try to load more details about the plugins so as to allow for command and + // flag completion of the plugin itself. + // We only do this when necessary (for the "completion" and "__complete" commands) to avoid the + // risk of a rogue plugin affecting Helm's normal behavior. + subCmd, _, err := baseCmd.Find(os.Args[1:]) + if (err == nil && (subCmd.Name() == "completion" || subCmd.Name() == completion.CompRequestCmd)) || + /* for the tests */ subCmd == baseCmd.Root() { + loadCompletionForPlugin(c, plug) + } + } +} - completion.CompDebugln(fmt.Sprintf("calling %s with args %v", main, argv)) - buf := new(bytes.Buffer) - if err := callPluginExecutable(cmd, main, argv, buf); err != nil { - return nil, completion.BashCompDirectiveError - } +func processParent(cmd *cobra.Command, args []string) ([]string, error) { + k, u := manuallyProcessArgs(args) + if err := cmd.Parent().ParseFlags(k); err != nil { + return nil, err + } + return u, nil +} - var completions []string - for _, comp := range strings.Split(buf.String(), "\n") { - // Remove any empty lines - if len(comp) > 0 { - completions = append(completions, comp) - } - } +// This function is used to setup the environment for the plugin and then +// call the executable specified by the parameter 'main' +func callPluginExecutable(pluginName string, main string, argv []string, out io.Writer) error { + env := os.Environ() + for k, v := range settings.EnvVars() { + env = append(env, fmt.Sprintf("%s=%s", k, v)) + } - // Check if the last line of output is of the form :, which - // indicates the BashCompletionDirective. - directive := completion.BashCompDirectiveDefault - if len(completions) > 0 { - lastLine := completions[len(completions)-1] - if len(lastLine) > 1 && lastLine[0] == ':' { - if strInt, err := strconv.Atoi(lastLine[1:]); err == nil { - directive = completion.BashCompDirective(strInt) - completions = completions[:len(completions)-1] - } - } + prog := exec.Command(main, argv...) + prog.Env = env + prog.Stdin = os.Stdin + prog.Stdout = out + prog.Stderr = os.Stderr + if err := prog.Run(); err != nil { + if eerr, ok := err.(*exec.ExitError); ok { + os.Stderr.Write(eerr.Stderr) + status := eerr.Sys().(syscall.WaitStatus) + return pluginError{ + error: errors.Errorf("plugin %q exited with error", pluginName), + code: status.ExitStatus(), } - - return completions, directive - }) - - // TODO: Make sure a command with this name does not already exist. - baseCmd.AddCommand(c) + } + return err } + return nil } // manuallyProcessArgs processes an arg array, removing special args. @@ -246,35 +201,31 @@ type pluginCommand struct { Commands []pluginCommand `json:"commands"` } -// loadPluginsForCompletion will load and parse any completion.yaml provided by the plugins -func loadPluginsForCompletion(baseCmd *cobra.Command, plugins []*plugin.Plugin) { - for _, plug := range plugins { - // Parse the yaml file providing the plugin's subcmds and flags - cmds, err := loadFile(strings.Join( - []string{plug.Dir, pluginStaticCompletionFile}, string(filepath.Separator))) - - if err != nil { - // The file could be missing or invalid. Either way, we at least create the command - // for the plugin name. - if settings.Debug { - log.Output(2, fmt.Sprintf("[info] %s\n", err.Error())) - } - cmds = &pluginCommand{Name: plug.Metadata.Name} +// loadCompletionForPlugin will load and parse any completion.yaml provided by the plugin +// and add the dynamic completion hook to call the optional plugin.complete +func loadCompletionForPlugin(pluginCmd *cobra.Command, plugin *plugin.Plugin) { + // Parse the yaml file providing the plugin's sub-commands and flags + cmds, err := loadFile(strings.Join( + []string{plugin.Dir, pluginStaticCompletionFile}, string(filepath.Separator))) + + if err != nil { + // The file could be missing or invalid. No static completion for this plugin. + if settings.Debug { + log.Output(2, fmt.Sprintf("[info] %s\n", err.Error())) } + // Continue to setup dynamic completion. + cmds = &pluginCommand{} + } - // We know what the plugin name must be. - // Let's set it in case the Name field was not specified correctly in the file. - // This insures that we will at least get the plugin name to complete, even if - // there is a problem with the completion.yaml file - cmds.Name = plug.Metadata.Name + // Preserve the Usage string specified for the plugin + cmds.Name = pluginCmd.Use - addPluginCommands(baseCmd, cmds) - } + addPluginCommands(plugin, pluginCmd, cmds) } -// addPluginCommands is a recursive method that adds the different levels -// of sub-commands and flags for the plugins that provide such information -func addPluginCommands(baseCmd *cobra.Command, cmds *pluginCommand) { +// addPluginCommands is a recursive method that adds each different level +// of sub-commands and flags for the plugins that have provided such information +func addPluginCommands(plugin *plugin.Plugin, baseCmd *cobra.Command, cmds *pluginCommand) { if cmds == nil { return } @@ -287,14 +238,19 @@ func addPluginCommands(baseCmd *cobra.Command, cmds *pluginCommand) { return } - // Create a fake command just so the completion script will include it - c := &cobra.Command{ - Use: cmds.Name, - ValidArgs: cmds.ValidArgs, - // A Run is required for it to be a valid command without subcommands - Run: func(cmd *cobra.Command, args []string) {}, + baseCmd.Use = cmds.Name + baseCmd.ValidArgs = cmds.ValidArgs + // Setup the same dynamic completion for each plugin sub-command. + // This is because if dynamic completion is triggered, there is a single executable + // to call (plugin.complete), so every sub-commands calls it in the same fashion. + if cmds.Commands == nil { + // Only setup dynamic completion if there are no sub-commands. This avoids + // calling plugin.complete at every completion, which greatly simplifies + // development of plugin.complete for plugin developers. + completion.RegisterValidArgsFunc(baseCmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + return pluginDynamicComp(plugin, cmd, args, toComplete) + }) } - baseCmd.AddCommand(c) // Create fake flags. if len(cmds.Flags) > 0 { @@ -314,7 +270,7 @@ func addPluginCommands(baseCmd *cobra.Command, cmds *pluginCommand) { } } - f := c.Flags() + f := baseCmd.Flags() if len(longs) >= len(shorts) { for i := range longs { if i < len(shorts) { @@ -338,7 +294,16 @@ func addPluginCommands(baseCmd *cobra.Command, cmds *pluginCommand) { // Recursively add any sub-commands for _, cmd := range cmds.Commands { - addPluginCommands(c, &cmd) + // Create a fake command so that completion can be done for the sub-commands of the plugin + subCmd := &cobra.Command{ + // This prevents Cobra from removing the flags. We want to keep the flags to pass them + // to the dynamic completion script of the plugin. + DisableFlagParsing: true, + // A Run is required for it to be a valid command without subcommands + Run: func(cmd *cobra.Command, args []string) {}, + } + baseCmd.AddCommand(subCmd) + addPluginCommands(plugin, subCmd, &cmd) } } @@ -353,3 +318,59 @@ func loadFile(path string) (*pluginCommand, error) { err = yaml.Unmarshal(b, cmds) return cmds, err } + +// pluginDynamicComp call the plugin.complete script of the plugin (if available) +// to obtain the dynamic completion choices. It must pass all the flags and sub-commands +// specified in the command-line to the plugin.complete executable (except helm's global flags) +func pluginDynamicComp(plug *plugin.Plugin, cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + md := plug.Metadata + + u, err := processParent(cmd, args) + if err != nil { + return nil, completion.BashCompDirectiveError + } + + // We will call the dynamic completion script of the plugin + main := strings.Join([]string{plug.Dir, pluginDynamicCompletionExecutable}, string(filepath.Separator)) + + // We must include all sub-commands passed on the command-line. + // To do that, we pass-in the entire CommandPath, except the first two elements + // which are 'helm' and 'pluginName'. + argv := strings.Split(cmd.CommandPath(), " ")[2:] + if !md.IgnoreFlags { + argv = append(argv, u...) + argv = append(argv, toComplete) + } + plugin.SetupPluginEnv(settings, md.Name, plug.Dir) + + completion.CompDebugln(fmt.Sprintf("calling %s with args %v", main, argv)) + buf := new(bytes.Buffer) + if err := callPluginExecutable(md.Name, main, argv, buf); err != nil { + // The dynamic completion file is optional for a plugin, so this error is ok. + completion.CompDebugln(fmt.Sprintf("Unable to call %s: %v", main, err.Error())) + return nil, completion.BashCompDirectiveDefault + } + + var completions []string + for _, comp := range strings.Split(buf.String(), "\n") { + // Remove any empty lines + if len(comp) > 0 { + completions = append(completions, comp) + } + } + + // Check if the last line of output is of the form :, which + // indicates the BashCompletionDirective. + directive := completion.BashCompDirectiveDefault + if len(completions) > 0 { + lastLine := completions[len(completions)-1] + if len(lastLine) > 1 && lastLine[0] == ':' { + if strInt, err := strconv.Atoi(lastLine[1:]); err == nil { + directive = completion.BashCompDirective(strInt) + completions = completions[:len(completions)-1] + } + } + } + + return completions, directive +} From e6069769151b91c91a107bd4d79ca3a941658518 Mon Sep 17 00:00:00 2001 From: Maksim Kochkin Date: Fri, 15 May 2020 16:38:55 +0300 Subject: [PATCH 25/66] Add new line to fix code formatting in doc Signed-off-by: Maksim Kochkin --- cmd/helm/install.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/helm/install.go b/cmd/helm/install.go index 21a41b9f9..44f7336c0 100644 --- a/cmd/helm/install.go +++ b/cmd/helm/install.go @@ -60,6 +60,7 @@ or $ helm install --set-string long_int=1234567890 myredis ./redis or + $ helm install --set-file my_script=dothings.sh myredis ./redis You can specify the '--values'/'-f' flag multiple times. The priority will be given to the From 118d46eb3e2c8425ecdbb9c8f8270413060eda78 Mon Sep 17 00:00:00 2001 From: Matt Butcher Date: Fri, 15 May 2020 12:08:15 -0600 Subject: [PATCH 26/66] feat: Detect missing selector during lint Signed-off-by: Matt Butcher --- pkg/lint/rules/template.go | 14 ++++++ pkg/lint/rules/template_test.go | 81 ++++++++++++++++++++++++++++++++- 2 files changed, 94 insertions(+), 1 deletion(-) diff --git a/pkg/lint/rules/template.go b/pkg/lint/rules/template.go index 787c5b26a..0c8e872b7 100644 --- a/pkg/lint/rules/template.go +++ b/pkg/lint/rules/template.go @@ -131,6 +131,7 @@ func Templates(linter *support.Linter, values map[string]interface{}, namespace linter.RunLinterRule(support.ErrorSev, path, validateYamlContent(err)) linter.RunLinterRule(support.ErrorSev, path, validateMetadataName(&yamlStruct)) linter.RunLinterRule(support.ErrorSev, path, validateNoDeprecations(&yamlStruct)) + linter.RunLinterRule(support.ErrorSev, path, validateMatchSelector(&yamlStruct, renderedContent)) } } } @@ -185,6 +186,19 @@ func validateNoReleaseTime(manifest []byte) error { return nil } +// validateMatchSelector ensures that template specs have a selector declared. +// See https://github.com/helm/helm/issues/1990 +func validateMatchSelector(yamlStruct *K8sYamlStruct, manifest string) error { + switch yamlStruct.Kind { + case "Deployment", "ReplicaSet", "DaemonSet", "StatefulSet": + // verify that matchLabels or matchExpressions is present + if !(strings.Contains(manifest, "matchLabels") || strings.Contains(manifest, "matchExpressions")) { + return fmt.Errorf("a %s must contain matchLabels or matchExpressions, and %q does not", yamlStruct.Kind, yamlStruct.Metadata.Name) + } + } + return nil +} + // K8sYamlStruct stubs a Kubernetes YAML file. // // DEPRECATED: In Helm 4, this will be made a private type, as it is for use only within diff --git a/pkg/lint/rules/template_test.go b/pkg/lint/rules/template_test.go index 991c6c2f6..ae82c8922 100644 --- a/pkg/lint/rules/template_test.go +++ b/pkg/lint/rules/template_test.go @@ -145,7 +145,7 @@ func TestDeprecatedAPIFails(t *testing.T) { Templates: []*chart.File{ { Name: "templates/baddeployment.yaml", - Data: []byte("apiVersion: apps/v1beta1\nkind: Deployment\nmetadata:\n name: baddep"), + Data: []byte("apiVersion: apps/v1beta1\nkind: Deployment\nmetadata:\n name: baddep\nspec: {selector: {matchLabels: {foo: bar}}}"), }, { Name: "templates/goodsecret.yaml", @@ -226,3 +226,82 @@ func TestStrictTemplateParsingMapError(t *testing.T) { } } } + +func TestValidateMatchSelector(t *testing.T) { + md := &K8sYamlStruct{ + APIVersion: "apps/v1", + Kind: "Deployment", + Metadata: k8sYamlMetadata{ + Name: "mydeployment", + }, + } + manifest := ` + apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx-deployment + labels: + app: nginx +spec: + replicas: 3 + selector: + matchLabels: + app: nginx + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:1.14.2 + ` + if err := validateMatchSelector(md, manifest); err != nil { + t.Error(err) + } + manifest = ` + apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx-deployment + labels: + app: nginx +spec: + replicas: 3 + selector: + matchExpressions: + app: nginx + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:1.14.2 + ` + if err := validateMatchSelector(md, manifest); err != nil { + t.Error(err) + } + manifest = ` + apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx-deployment + labels: + app: nginx +spec: + replicas: 3 + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:1.14.2 + ` + if err := validateMatchSelector(md, manifest); err == nil { + t.Error("expected Deployment with no selector to fail") + } +} From 3364265e78274577be049763b54adffb9913d75d Mon Sep 17 00:00:00 2001 From: Adam Reese Date: Fri, 15 May 2020 12:11:18 -0700 Subject: [PATCH 27/66] ref(pkg/chartutil): use minimal in-memory fixtures Signed-off-by: Adam Reese --- pkg/chartutil/coalesce_test.go | 43 +++++++++++++++++- pkg/chartutil/create_test.go | 2 +- .../frobnitz/charts/mariner-4.3.2.tgz | Bin 962 -> 0 bytes .../{ => frobnitz/charts}/mariner/Chart.yaml | 0 .../mariner/charts}/albatross/Chart.yaml | 0 .../mariner/charts}/albatross/values.yaml | 0 .../charts}/mariner/templates/placeholder.tpl | 0 .../{ => frobnitz/charts}/mariner/values.yaml | 0 .../testdata/frobnitz_backslash/.helmignore | 1 - .../testdata/frobnitz_backslash/Chart.lock | 8 ---- .../testdata/frobnitz_backslash/Chart.yaml | 27 ----------- .../testdata/frobnitz_backslash/INSTALL.txt | 1 - .../testdata/frobnitz_backslash/LICENSE | 1 - .../testdata/frobnitz_backslash/README.md | 11 ----- .../frobnitz_backslash/charts/_ignore_me | 1 - .../charts/alpine/Chart.yaml | 5 -- .../charts/alpine/README.md | 9 ---- .../charts/alpine/charts/mast1/Chart.yaml | 5 -- .../charts/alpine/charts/mast1/values.yaml | 4 -- .../charts/alpine/charts/mast2-0.1.0.tgz | Bin 252 -> 0 bytes .../charts/alpine/templates/alpine-pod.yaml | 14 ------ .../charts/alpine/values.yaml | 2 - .../charts/mariner-4.3.2.tgz | Bin 962 -> 0 bytes .../frobnitz_backslash/docs/README.md | 1 - .../testdata/frobnitz_backslash/icon.svg | 8 ---- .../testdata/frobnitz_backslash/ignore/me.txt | 0 .../frobnitz_backslash/templates/template.tpl | 1 - .../testdata/frobnitz_backslash/values.yaml | 6 --- .../mariner/charts/albatross-0.1.0.tgz | Bin 305 -> 0 bytes pkg/chartutil/testdata/moby/Chart.yaml | 4 -- .../testdata/moby/charts/pequod/Chart.yaml | 4 -- .../moby/charts/pequod/charts/ahab/Chart.yaml | 4 -- .../charts/pequod/charts/ahab/values.yaml | 6 --- .../testdata/moby/charts/pequod/values.yaml | 2 - .../testdata/moby/charts/spouter/Chart.yaml | 4 -- .../testdata/moby/charts/spouter/values.yaml | 1 - pkg/chartutil/testdata/moby/values.yaml | 11 ----- 37 files changed, 43 insertions(+), 143 deletions(-) delete mode 100644 pkg/chartutil/testdata/frobnitz/charts/mariner-4.3.2.tgz rename pkg/chartutil/testdata/{ => frobnitz/charts}/mariner/Chart.yaml (100%) rename pkg/chartutil/testdata/{ => frobnitz/charts/mariner/charts}/albatross/Chart.yaml (100%) rename pkg/chartutil/testdata/{ => frobnitz/charts/mariner/charts}/albatross/values.yaml (100%) rename pkg/chartutil/testdata/{ => frobnitz/charts}/mariner/templates/placeholder.tpl (100%) rename pkg/chartutil/testdata/{ => frobnitz/charts}/mariner/values.yaml (100%) delete mode 100755 pkg/chartutil/testdata/frobnitz_backslash/.helmignore delete mode 100755 pkg/chartutil/testdata/frobnitz_backslash/Chart.lock delete mode 100755 pkg/chartutil/testdata/frobnitz_backslash/Chart.yaml delete mode 100755 pkg/chartutil/testdata/frobnitz_backslash/INSTALL.txt delete mode 100755 pkg/chartutil/testdata/frobnitz_backslash/LICENSE delete mode 100755 pkg/chartutil/testdata/frobnitz_backslash/README.md delete mode 100755 pkg/chartutil/testdata/frobnitz_backslash/charts/_ignore_me delete mode 100755 pkg/chartutil/testdata/frobnitz_backslash/charts/alpine/Chart.yaml delete mode 100755 pkg/chartutil/testdata/frobnitz_backslash/charts/alpine/README.md delete mode 100755 pkg/chartutil/testdata/frobnitz_backslash/charts/alpine/charts/mast1/Chart.yaml delete mode 100755 pkg/chartutil/testdata/frobnitz_backslash/charts/alpine/charts/mast1/values.yaml delete mode 100755 pkg/chartutil/testdata/frobnitz_backslash/charts/alpine/charts/mast2-0.1.0.tgz delete mode 100755 pkg/chartutil/testdata/frobnitz_backslash/charts/alpine/templates/alpine-pod.yaml delete mode 100755 pkg/chartutil/testdata/frobnitz_backslash/charts/alpine/values.yaml delete mode 100755 pkg/chartutil/testdata/frobnitz_backslash/charts/mariner-4.3.2.tgz delete mode 100755 pkg/chartutil/testdata/frobnitz_backslash/docs/README.md delete mode 100755 pkg/chartutil/testdata/frobnitz_backslash/icon.svg delete mode 100755 pkg/chartutil/testdata/frobnitz_backslash/ignore/me.txt delete mode 100755 pkg/chartutil/testdata/frobnitz_backslash/templates/template.tpl delete mode 100755 pkg/chartutil/testdata/frobnitz_backslash/values.yaml delete mode 100644 pkg/chartutil/testdata/mariner/charts/albatross-0.1.0.tgz delete mode 100644 pkg/chartutil/testdata/moby/Chart.yaml delete mode 100644 pkg/chartutil/testdata/moby/charts/pequod/Chart.yaml delete mode 100644 pkg/chartutil/testdata/moby/charts/pequod/charts/ahab/Chart.yaml delete mode 100644 pkg/chartutil/testdata/moby/charts/pequod/charts/ahab/values.yaml delete mode 100644 pkg/chartutil/testdata/moby/charts/pequod/values.yaml delete mode 100644 pkg/chartutil/testdata/moby/charts/spouter/Chart.yaml delete mode 100644 pkg/chartutil/testdata/moby/charts/spouter/values.yaml delete mode 100644 pkg/chartutil/testdata/moby/values.yaml diff --git a/pkg/chartutil/coalesce_test.go b/pkg/chartutil/coalesce_test.go index 2a3d848fa..5a4656d71 100644 --- a/pkg/chartutil/coalesce_test.go +++ b/pkg/chartutil/coalesce_test.go @@ -21,6 +21,8 @@ import ( "testing" "github.com/stretchr/testify/assert" + + "helm.sh/helm/v3/pkg/chart" ) // ref: http://www.yaml.org/spec/1.2/spec.html#id2803362 @@ -55,9 +57,48 @@ pequod: bar: null `) +func withDeps(c *chart.Chart, deps ...*chart.Chart) *chart.Chart { + c.AddDependency(deps...) + return c +} + func TestCoalesceValues(t *testing.T) { is := assert.New(t) - c := loadChart(t, "testdata/moby") + + c := withDeps(&chart.Chart{ + Metadata: &chart.Metadata{Name: "moby"}, + Values: map[string]interface{}{ + "back": "exists", + "bottom": "exists", + "front": "exists", + "left": "exists", + "name": "moby", + "nested": map[string]interface{}{"boat": true}, + "override": "bad", + "right": "exists", + "scope": "moby", + "top": "nope", + }, + }, + withDeps(&chart.Chart{ + Metadata: &chart.Metadata{Name: "pequod"}, + Values: map[string]interface{}{"name": "pequod", "scope": "pequod"}, + }, + &chart.Chart{ + Metadata: &chart.Metadata{Name: "ahab"}, + Values: map[string]interface{}{ + "scope": "ahab", + "name": "ahab", + "boat": true, + "nested": map[string]interface{}{"foo": false, "bar": true}, + }, + }, + ), + &chart.Chart{ + Metadata: &chart.Metadata{Name: "spouter"}, + Values: map[string]interface{}{"scope": "spouter"}, + }, + ) vals, err := ReadValues(testCoalesceValuesYaml) if err != nil { diff --git a/pkg/chartutil/create_test.go b/pkg/chartutil/create_test.go index d2a3b0a20..a11c45140 100644 --- a/pkg/chartutil/create_test.go +++ b/pkg/chartutil/create_test.go @@ -81,7 +81,7 @@ func TestCreateFrom(t *testing.T) { Name: "foo", Version: "0.1.0", } - srcdir := "./testdata/mariner" + srcdir := "./testdata/frobnitz/charts/mariner" if err := CreateFrom(cf, tdir, srcdir); err != nil { t.Fatal(err) diff --git a/pkg/chartutil/testdata/frobnitz/charts/mariner-4.3.2.tgz b/pkg/chartutil/testdata/frobnitz/charts/mariner-4.3.2.tgz deleted file mode 100644 index 5648f6f6daa6b69765cb792f5926add825926dfc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 962 zcmV;z13mm7iwFRyACz1G1MQbxXcR{rzz+gJ7NkO|K16!MMWkA?*}eTZb5%on8bXs; zTaH9)Ax`e*a*O-b*|}hhHsC|6sZ=bjZ6z;NC>li(eXv3+5jBV+3c(J{0;`~^c-MiWUe|G+#V?eB#2v_+Eh#&|dMFHNZs@^CB!ACg%JQ@AFNsXB}MnCmDYVPVjaYD3sW1UXzsPK3-$e2`08u9QH43b2tGM`lbzPM8Cr z5@Z!Xy$upnd+ zU|nrfVubP<8g>A& zK%0B-I8>fy(#K9Kg+V?Yx%#s`L%@42z;TmS=k^qI5(xu>Q;0PIFV55XpAIpUwDdT_ zJh5jY8%!7fGyzPF{~$d93M~GM!Q|+kYVHx2e>ux{!2iuBzLL?w2J?(Cr*y-$73a2>tSQ$kP|LA{gIn*HE?W5Y zj@_dmb8q&p(t}G#WNgj2CH3gle_U$pZ9TOh^8Oq9`|B4EpT8o0+_e+;eQ;;zVB^N+ z$2txU^Uw7cTl<#JE7?$F5gKYuCv`%?GO@gtx8{{77>Z=Pt`_vw26fW;k4pXkZ( z{vrR!j)!}izo`2$xN@`k-GcJVy=NaioKyW_+2THXY5THyHCt;=jt0lOhS#r-Jn;Rx zw_8j5hi~kyPLIEPH*@Dc zVQyr3R8em|NM&qo0PNJUs=_c72H?(liabH@pWIst-7YSIyL+rhEHrIN(t?QZE=F{y zgNRfS&$pa5Ly`mMk2OB%pV`*9knW7FlL-Joo@KED7*{C$d;N~z z37$S{+}wvSU9}|VtF|fRpv9Ve>8dWo|9?5B+RE}Y9CFh-x#(Bq8Vck^V=NUiPLCKa z8z5CF#JgK!4>;$4Fm+FUst4d+{(+nP|0&J+e}(;l^U4@w-{=?s0RR8vgVbLD3;+OM Cs&R<` diff --git a/pkg/chartutil/testdata/frobnitz_backslash/charts/alpine/templates/alpine-pod.yaml b/pkg/chartutil/testdata/frobnitz_backslash/charts/alpine/templates/alpine-pod.yaml deleted file mode 100755 index 5bbae10af..000000000 --- a/pkg/chartutil/testdata/frobnitz_backslash/charts/alpine/templates/alpine-pod.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - name: {{.Release.Name}}-{{.Chart.Name}} - labels: - app.kubernetes.io/managed-by: {{.Release.Service}} - chartName: {{.Chart.Name}} - chartVersion: {{.Chart.Version | quote}} -spec: - restartPolicy: {{default "Never" .restart_policy}} - containers: - - name: waiter - image: "alpine:3.3" - command: ["/bin/sleep","9000"] diff --git a/pkg/chartutil/testdata/frobnitz_backslash/charts/alpine/values.yaml b/pkg/chartutil/testdata/frobnitz_backslash/charts/alpine/values.yaml deleted file mode 100755 index 6c2aab7ba..000000000 --- a/pkg/chartutil/testdata/frobnitz_backslash/charts/alpine/values.yaml +++ /dev/null @@ -1,2 +0,0 @@ -# The pod name -name: "my-alpine" diff --git a/pkg/chartutil/testdata/frobnitz_backslash/charts/mariner-4.3.2.tgz b/pkg/chartutil/testdata/frobnitz_backslash/charts/mariner-4.3.2.tgz deleted file mode 100755 index 5648f6f6daa6b69765cb792f5926add825926dfc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 962 zcmV;z13mm7iwFRyACz1G1MQbxXcR{rzz+gJ7NkO|K16!MMWkA?*}eTZb5%on8bXs; zTaH9)Ax`e*a*O-b*|}hhHsC|6sZ=bjZ6z;NC>li(eXv3+5jBV+3c(J{0;`~^c-MiWUe|G+#V?eB#2v_+Eh#&|dMFHNZs@^CB!ACg%JQ@AFNsXB}MnCmDYVPVjaYD3sW1UXzsPK3-$e2`08u9QH43b2tGM`lbzPM8Cr z5@Z!Xy$upnd+ zU|nrfVubP<8g>A& zK%0B-I8>fy(#K9Kg+V?Yx%#s`L%@42z;TmS=k^qI5(xu>Q;0PIFV55XpAIpUwDdT_ zJh5jY8%!7fGyzPF{~$d93M~GM!Q|+kYVHx2e>ux{!2iuBzLL?w2J?(Cr*y-$73a2>tSQ$kP|LA{gIn*HE?W5Y zj@_dmb8q&p(t}G#WNgj2CH3gle_U$pZ9TOh^8Oq9`|B4EpT8o0+_e+;eQ;;zVB^N+ z$2txU^Uw7cTl<#JE7?$F5gKYuCv`%?GO@gtx8{{77>Z=Pt`_vw26fW;k4pXkZ( z{vrR!j)!}izo`2$xN@`k-GcJVy=NaioKyW_+2THXY5THyHCt;=jt0lOhS#r-Jn;Rx zw_8j5hi~kyPLIEPH*@ - - Example icon - - - diff --git a/pkg/chartutil/testdata/frobnitz_backslash/ignore/me.txt b/pkg/chartutil/testdata/frobnitz_backslash/ignore/me.txt deleted file mode 100755 index e69de29bb..000000000 diff --git a/pkg/chartutil/testdata/frobnitz_backslash/templates/template.tpl b/pkg/chartutil/testdata/frobnitz_backslash/templates/template.tpl deleted file mode 100755 index c651ee6a0..000000000 --- a/pkg/chartutil/testdata/frobnitz_backslash/templates/template.tpl +++ /dev/null @@ -1 +0,0 @@ -Hello {{.Name | default "world"}} diff --git a/pkg/chartutil/testdata/frobnitz_backslash/values.yaml b/pkg/chartutil/testdata/frobnitz_backslash/values.yaml deleted file mode 100755 index 61f501258..000000000 --- a/pkg/chartutil/testdata/frobnitz_backslash/values.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# A values file contains configuration. - -name: "Some Name" - -section: - name: "Name in a section" diff --git a/pkg/chartutil/testdata/mariner/charts/albatross-0.1.0.tgz b/pkg/chartutil/testdata/mariner/charts/albatross-0.1.0.tgz deleted file mode 100644 index 22c1fe57251c27c11d6e6b5c518fc998d62d5bfd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 305 zcmV-10nYv(iwFRyACz1G1MSpHZo)7S24L1c#fSq?8*C$GSFx$oefI_?B$A1d?I88` z4UYz?Ds)5oQ2%c;iflRK%uJkLx*S7F52L|IDd)z}F4@aL6Zy=4um7%o;h5^s6tq{Oaa%5^Zwj&Iw2JjEAJ-r0iT##Vhen|? zM0#$Q92?G@#QyydIZ+cSs&F`GJQhEFKe+8O|9j_KPDA_vzM6k&<{#(ZnmOkGJM{JM zrZvZw$3kp;SUO(_BG=|B#DW&VbF9}J#yA520000000000000000Q^R8xfQyO04M+e DGPIJ| diff --git a/pkg/chartutil/testdata/moby/Chart.yaml b/pkg/chartutil/testdata/moby/Chart.yaml deleted file mode 100644 index a5f992c61..000000000 --- a/pkg/chartutil/testdata/moby/Chart.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: v1 -description: A Helm chart for Kubernetes -name: moby -version: 0.1.0 diff --git a/pkg/chartutil/testdata/moby/charts/pequod/Chart.yaml b/pkg/chartutil/testdata/moby/charts/pequod/Chart.yaml deleted file mode 100644 index f1a8ef76b..000000000 --- a/pkg/chartutil/testdata/moby/charts/pequod/Chart.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: v1 -description: A Helm chart for Kubernetes -name: pequod -version: 0.1.0 diff --git a/pkg/chartutil/testdata/moby/charts/pequod/charts/ahab/Chart.yaml b/pkg/chartutil/testdata/moby/charts/pequod/charts/ahab/Chart.yaml deleted file mode 100644 index a7ee7bf90..000000000 --- a/pkg/chartutil/testdata/moby/charts/pequod/charts/ahab/Chart.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: v1 -description: A Helm chart for Kubernetes -name: ahab -version: 0.1.0 diff --git a/pkg/chartutil/testdata/moby/charts/pequod/charts/ahab/values.yaml b/pkg/chartutil/testdata/moby/charts/pequod/charts/ahab/values.yaml deleted file mode 100644 index eee6980fa..000000000 --- a/pkg/chartutil/testdata/moby/charts/pequod/charts/ahab/values.yaml +++ /dev/null @@ -1,6 +0,0 @@ -scope: ahab -name: ahab -boat: true -nested: - foo: false - bar: true diff --git a/pkg/chartutil/testdata/moby/charts/pequod/values.yaml b/pkg/chartutil/testdata/moby/charts/pequod/values.yaml deleted file mode 100644 index d6e34b274..000000000 --- a/pkg/chartutil/testdata/moby/charts/pequod/values.yaml +++ /dev/null @@ -1,2 +0,0 @@ -scope: pequod -name: pequod diff --git a/pkg/chartutil/testdata/moby/charts/spouter/Chart.yaml b/pkg/chartutil/testdata/moby/charts/spouter/Chart.yaml deleted file mode 100644 index 0525085b6..000000000 --- a/pkg/chartutil/testdata/moby/charts/spouter/Chart.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: v1 -description: A Helm chart for Kubernetes -name: spouter -version: 0.1.0 diff --git a/pkg/chartutil/testdata/moby/charts/spouter/values.yaml b/pkg/chartutil/testdata/moby/charts/spouter/values.yaml deleted file mode 100644 index f71d92a9f..000000000 --- a/pkg/chartutil/testdata/moby/charts/spouter/values.yaml +++ /dev/null @@ -1 +0,0 @@ -scope: spouter diff --git a/pkg/chartutil/testdata/moby/values.yaml b/pkg/chartutil/testdata/moby/values.yaml deleted file mode 100644 index 2169d7566..000000000 --- a/pkg/chartutil/testdata/moby/values.yaml +++ /dev/null @@ -1,11 +0,0 @@ -scope: moby -name: moby -override: bad -top: nope -bottom: exists -right: exists -left: exists -front: exists -back: exists -nested: - boat: true From bade6478fcdd537957f0ce8a2cc5e06a14940ea0 Mon Sep 17 00:00:00 2001 From: Matt Farina Date: Fri, 15 May 2020 13:23:10 -0400 Subject: [PATCH 28/66] Fixing error with strvals parsing Closes #8140 Signed-off-by: Matt Farina --- pkg/strvals/parser.go | 30 +++++++++++++++++++++------- pkg/strvals/parser_test.go | 41 +++++++++++++++++++++++++++++++++++--- 2 files changed, 61 insertions(+), 10 deletions(-) diff --git a/pkg/strvals/parser.go b/pkg/strvals/parser.go index 03adbd3cb..db2fb60fe 100644 --- a/pkg/strvals/parser.go +++ b/pkg/strvals/parser.go @@ -17,6 +17,7 @@ package strvals import ( "bytes" + "fmt" "io" "strconv" "strings" @@ -230,14 +231,17 @@ func set(data map[string]interface{}, key string, val interface{}) { data[key] = val } -func setIndex(list []interface{}, index int, val interface{}) []interface{} { +func setIndex(list []interface{}, index int, val interface{}) ([]interface{}, error) { + if index < 0 { + return list, fmt.Errorf("negative %d index not allowed", index) + } if len(list) <= index { newlist := make([]interface{}, index+1) copy(newlist, list) list = newlist } list[index] = val - return list + return list, nil } func (t *parser) keyIndex() (int, error) { @@ -252,6 +256,9 @@ func (t *parser) keyIndex() (int, error) { } func (t *parser) listItem(list []interface{}, i int) ([]interface{}, error) { + if i < 0 { + return list, fmt.Errorf("negative %d index not allowed", i) + } stop := runeSet([]rune{'[', '.', '='}) switch k, last, err := runesUntil(t.sc, stop); { case len(k) > 0: @@ -262,16 +269,19 @@ func (t *parser) listItem(list []interface{}, i int) ([]interface{}, error) { vl, e := t.valList() switch e { case nil: - return setIndex(list, i, vl), nil + return setIndex(list, i, vl) case io.EOF: - return setIndex(list, i, ""), err + return setIndex(list, i, "") case ErrNotList: rs, e := t.val() if e != nil && e != io.EOF { return list, e } v, e := t.reader(rs) - return setIndex(list, i, v), e + if e != nil { + return list, e + } + return setIndex(list, i, v) default: return list, e } @@ -283,7 +293,10 @@ func (t *parser) listItem(list []interface{}, i int) ([]interface{}, error) { } // Now we need to get the value after the ]. list2, err := t.listItem(list, i) - return setIndex(list, i, list2), err + if err != nil { + return list, err + } + return setIndex(list, i, list2) case last == '.': // We have a nested object. Send to t.key inner := map[string]interface{}{} @@ -299,7 +312,10 @@ func (t *parser) listItem(list []interface{}, i int) ([]interface{}, error) { // Recurse e := t.key(inner) - return setIndex(list, i, inner), e + if e != nil { + return list, e + } + return setIndex(list, i, inner) default: return nil, errors.Errorf("parse error: unexpected token %v", last) } diff --git a/pkg/strvals/parser_test.go b/pkg/strvals/parser_test.go index 44d317220..fb18980cf 100644 --- a/pkg/strvals/parser_test.go +++ b/pkg/strvals/parser_test.go @@ -28,6 +28,7 @@ func TestSetIndex(t *testing.T) { expect []interface{} add int val int + err bool }{ { name: "short", @@ -35,6 +36,7 @@ func TestSetIndex(t *testing.T) { expect: []interface{}{0, 1, 2}, add: 2, val: 2, + err: false, }, { name: "equal", @@ -42,6 +44,7 @@ func TestSetIndex(t *testing.T) { expect: []interface{}{0, 2}, add: 1, val: 2, + err: false, }, { name: "long", @@ -49,17 +52,41 @@ func TestSetIndex(t *testing.T) { expect: []interface{}{0, 1, 2, 4, 4, 5}, add: 3, val: 4, + err: false, + }, + { + name: "negative", + initial: []interface{}{0, 1, 2, 3, 4, 5}, + expect: []interface{}{0, 1, 2, 3, 4, 5}, + add: -1, + val: 4, + err: true, }, } for _, tt := range tests { - got := setIndex(tt.initial, tt.add, tt.val) + got, err := setIndex(tt.initial, tt.add, tt.val) + + if err != nil && tt.err == false { + t.Fatalf("%s: Expected no error but error returned", tt.name) + } else if err == nil && tt.err == true { + t.Fatalf("%s: Expected error but no error returned", tt.name) + } + if len(got) != len(tt.expect) { t.Fatalf("%s: Expected length %d, got %d", tt.name, len(tt.expect), len(got)) } - if gg := got[tt.add].(int); gg != tt.val { - t.Errorf("%s, Expected value %d, got %d", tt.name, tt.val, gg) + if !tt.err { + if gg := got[tt.add].(int); gg != tt.val { + t.Errorf("%s, Expected value %d, got %d", tt.name, tt.val, gg) + } + } + + for k, v := range got { + if v != tt.expect[k] { + t.Errorf("%s, Expected value %d, got %d", tt.name, tt.expect[k], v) + } } } } @@ -271,6 +298,10 @@ func TestParseSet(t *testing.T) { }, }, }, + { + str: "list[0].foo=bar,list[-30].hello=world", + err: true, + }, { str: "list[0]=foo,list[1]=bar", expect: map[string]interface{}{"list": []string{"foo", "bar"}}, @@ -283,6 +314,10 @@ func TestParseSet(t *testing.T) { str: "list[0]=foo,list[3]=bar", expect: map[string]interface{}{"list": []interface{}{"foo", nil, nil, "bar"}}, }, + { + str: "list[0]=foo,list[-20]=bar", + err: true, + }, { str: "illegal[0]name.foo=bar", err: true, From 8f1f0e0db2d96fa3d85c8b7a8e461f6bec7bced9 Mon Sep 17 00:00:00 2001 From: Matt Farina Date: Fri, 15 May 2020 16:00:57 -0400 Subject: [PATCH 29/66] Recovering from panic that can occur with make Signed-off-by: Matt Farina --- pkg/strvals/parser.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/pkg/strvals/parser.go b/pkg/strvals/parser.go index db2fb60fe..c52f38ab1 100644 --- a/pkg/strvals/parser.go +++ b/pkg/strvals/parser.go @@ -231,7 +231,16 @@ func set(data map[string]interface{}, key string, val interface{}) { data[key] = val } -func setIndex(list []interface{}, index int, val interface{}) ([]interface{}, error) { +func setIndex(list []interface{}, index int, val interface{}) (l2 []interface{}, err error) { + // There are possible index values that are out of range on a target system + // causing a panic. This will catch the panic and return an error instead. + // The value of the index that causes a panic varies from system to system. + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("error processing index %d: %s", index, r) + } + }() + if index < 0 { return list, fmt.Errorf("negative %d index not allowed", index) } From 6857da251edd416454827ac692c85de1ade6b5e6 Mon Sep 17 00:00:00 2001 From: Matt Farina Date: Fri, 15 May 2020 16:52:04 -0400 Subject: [PATCH 30/66] Catching a potential panic in strval parsing Signed-off-by: Matt Farina --- pkg/strvals/parser.go | 7 ++++++- pkg/strvals/parser_test.go | 4 ++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/pkg/strvals/parser.go b/pkg/strvals/parser.go index c52f38ab1..c735412e9 100644 --- a/pkg/strvals/parser.go +++ b/pkg/strvals/parser.go @@ -150,7 +150,12 @@ func runeSet(r []rune) map[rune]bool { return s } -func (t *parser) key(data map[string]interface{}) error { +func (t *parser) key(data map[string]interface{}) (reterr error) { + defer func() { + if r := recover(); r != nil { + reterr = fmt.Errorf("unable to parse key: %s", r) + } + }() stop := runeSet([]rune{'=', '[', ',', '.'}) for { switch k, last, err := runesUntil(t.sc, stop); { diff --git a/pkg/strvals/parser_test.go b/pkg/strvals/parser_test.go index fb18980cf..742256153 100644 --- a/pkg/strvals/parser_test.go +++ b/pkg/strvals/parser_test.go @@ -362,6 +362,10 @@ func TestParseSet(t *testing.T) { }, }, }, + { + str: "]={}].", + err: true, + }, } for _, tt := range tests { From 1a46c3495ab2aa101e31fe9dfbe10802bb7d0a63 Mon Sep 17 00:00:00 2001 From: Alan Zhu Date: Mon, 18 May 2020 09:25:19 +0800 Subject: [PATCH 31/66] Revert "group command for easy read" Signed-off-by: Alan Zhu --- cmd/helm/root.go | 63 ++++++++++++++++++------------------------------ 1 file changed, 23 insertions(+), 40 deletions(-) diff --git a/cmd/helm/root.go b/cmd/helm/root.go index ff4a01ad7..143745f29 100644 --- a/cmd/helm/root.go +++ b/cmd/helm/root.go @@ -26,7 +26,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/tools/clientcmd" - "k8s.io/kubectl/pkg/util/templates" "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/internal/experimental/registry" @@ -133,47 +132,31 @@ func newRootCmd(actionConfig *action.Configuration, out io.Writer, args []string flags.ParseErrorsWhitelist.UnknownFlags = true flags.Parse(args) - commandGroups := templates.CommandGroups{ - { - Message: "Release Management Commands:", - Commands: []*cobra.Command{ - newInstallCmd(actionConfig, out), - newListCmd(actionConfig, out), - newGetCmd(actionConfig, out), - newStatusCmd(actionConfig, out), - newUpgradeCmd(actionConfig, out), - newHistoryCmd(actionConfig, out), - newRollbackCmd(actionConfig, out), - newReleaseTestCmd(actionConfig, out), - newUninstallCmd(actionConfig, out), - }, - }, - { - Message: "Chart Commands:", - Commands: []*cobra.Command{ - newCreateCmd(out), - newDependencyCmd(out), - newPackageCmd(out), - newTemplateCmd(actionConfig, out), - newLintCmd(out), - newVerifyCmd(out), - }, - }, - { - Message: "Chart Repository Commands:", - Commands: []*cobra.Command{ - newRepoCmd(out), - newSearchCmd(out), - newPullCmd(out), - newShowCmd(out), - }, - }, - } - commandGroups.Add(cmd) - templates.ActsAsRootCommand(cmd, []string{"options"}, commandGroups...) - // Add subcommands cmd.AddCommand( + // chart commands + newCreateCmd(out), + newDependencyCmd(out), + newPullCmd(out), + newShowCmd(out), + newLintCmd(out), + newPackageCmd(out), + newRepoCmd(out), + newSearchCmd(out), + newVerifyCmd(out), + + // release commands + newGetCmd(actionConfig, out), + newHistoryCmd(actionConfig, out), + newInstallCmd(actionConfig, out), + newListCmd(actionConfig, out), + newReleaseTestCmd(actionConfig, out), + newRollbackCmd(actionConfig, out), + newStatusCmd(actionConfig, out), + newTemplateCmd(actionConfig, out), + newUninstallCmd(actionConfig, out), + newUpgradeCmd(actionConfig, out), + newCompletionCmd(out), newEnvCmd(out), newPluginCmd(out), From 5840e529e143d3f63539a312b81848f0b25ff6ba Mon Sep 17 00:00:00 2001 From: Thomas O'Donnell Date: Mon, 18 May 2020 16:40:40 +0200 Subject: [PATCH 32/66] Update the Helm version docs Have just updated the helm version docs to include the GoVersion field. Signed-off-by: Thomas O'Donnell --- cmd/helm/version.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmd/helm/version.go b/cmd/helm/version.go index b3f831e07..2f50c876c 100644 --- a/cmd/helm/version.go +++ b/cmd/helm/version.go @@ -33,12 +33,13 @@ Show the version for Helm. This will print a representation the version of Helm. The output will look something like this: -version.BuildInfo{Version:"v2.0.0", GitCommit:"ff52399e51bb880526e9cd0ed8386f6433b74da1", GitTreeState:"clean"} +version.BuildInfo{Version:"v3.2.1", GitCommit:"fe51cd1e31e6a202cba7dead9552a6d418ded79a", GitTreeState:"clean", GoVersion:"go1.13.10"} - Version is the semantic version of the release. - GitCommit is the SHA for the commit that this version was built from. - GitTreeState is "clean" if there are no local code changes when this binary was built, and "dirty" if the binary was built from locally modified code. +- GoVersion is the version of Go that was used to compile Helm. When using the --template flag the following properties are available to use in the template: From 2ae83f276b60085c550fc81fb6e21b38146e2d9f Mon Sep 17 00:00:00 2001 From: Martin Hickey Date: Mon, 18 May 2020 18:06:09 +0000 Subject: [PATCH 33/66] Fix repo cache setting Fix `repo add` and `repo update` to use a repository cache set using `--repository-cache` flag Signed-off-by: Martin Hickey Signed-off-by: Trond Hindenes --- cmd/helm/repo_add.go | 3 +++ cmd/helm/repo_update.go | 9 +++++++-- cmd/helm/repo_update_test.go | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/cmd/helm/repo_add.go b/cmd/helm/repo_add.go index 3d36fd0ed..9c67641e5 100644 --- a/cmd/helm/repo_add.go +++ b/cmd/helm/repo_add.go @@ -130,6 +130,9 @@ func (o *repoAddOptions) run(out io.Writer) error { return err } + if o.repoCache != "" { + r.CachePath = o.repoCache + } if _, err := r.DownloadIndexFile(); err != nil { return errors.Wrapf(err, "looks like %q is not a valid chart repository or cannot be reached", o.url) } diff --git a/cmd/helm/repo_update.go b/cmd/helm/repo_update.go index 027f18518..5c1086e81 100644 --- a/cmd/helm/repo_update.go +++ b/cmd/helm/repo_update.go @@ -37,8 +37,9 @@ Information is cached locally, where it is used by commands like 'helm search'. var errNoRepositories = errors.New("no repositories found. You must add one before updating") type repoUpdateOptions struct { - update func([]*repo.ChartRepository, io.Writer) - repoFile string + update func([]*repo.ChartRepository, io.Writer) + repoFile string + repoCache string } func newRepoUpdateCmd(out io.Writer) *cobra.Command { @@ -52,6 +53,7 @@ func newRepoUpdateCmd(out io.Writer) *cobra.Command { Args: require.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { o.repoFile = settings.RepositoryConfig + o.repoCache = settings.RepositoryCache return o.run(out) }, } @@ -69,6 +71,9 @@ func (o *repoUpdateOptions) run(out io.Writer) error { if err != nil { return err } + if o.repoCache != "" { + r.CachePath = o.repoCache + } repos = append(repos, r) } diff --git a/cmd/helm/repo_update_test.go b/cmd/helm/repo_update_test.go index 6ddce0637..b13d575e2 100644 --- a/cmd/helm/repo_update_test.go +++ b/cmd/helm/repo_update_test.go @@ -19,6 +19,8 @@ import ( "bytes" "fmt" "io" + "io/ioutil" + "path/filepath" "strings" "testing" @@ -79,3 +81,34 @@ func TestUpdateCharts(t *testing.T) { t.Error("Update was not successful") } } + +func TestUpdateChartsCustomCache(t *testing.T) { + defer resetEnv()() + defer ensure.HelmHome(t)() + + ts, err := repotest.NewTempServer("testdata/testserver/*.*") + if err != nil { + t.Fatal(err) + } + defer ts.Stop() + + r, err := repo.NewChartRepository(&repo.Entry{ + Name: "charts", + URL: ts.URL(), + }, getter.All(settings)) + if err != nil { + t.Error(err) + } + + cachePath := ensure.TempDir(t) + cacheFile := filepath.Join(cachePath, "charts-index.yaml") + r.CachePath = cachePath + + b := bytes.NewBuffer(nil) + updateCharts([]*repo.ChartRepository{r}, b) + + _, err = ioutil.ReadFile(cacheFile) + if err != nil { + t.Error(err) + } +} From 5600a2c82d236422e54b6089d5384dea44349900 Mon Sep 17 00:00:00 2001 From: Martin Hickey Date: Tue, 19 May 2020 15:45:14 +0000 Subject: [PATCH 34/66] Fix unit test Signed-off-by: Martin Hickey --- cmd/helm/repo_update_test.go | 52 ++++++++++++++---------------------- 1 file changed, 20 insertions(+), 32 deletions(-) diff --git a/cmd/helm/repo_update_test.go b/cmd/helm/repo_update_test.go index b13d575e2..981f0bba3 100644 --- a/cmd/helm/repo_update_test.go +++ b/cmd/helm/repo_update_test.go @@ -19,7 +19,7 @@ import ( "bytes" "fmt" "io" - "io/ioutil" + "os" "path/filepath" "strings" "testing" @@ -52,6 +52,25 @@ func TestUpdateCmd(t *testing.T) { } } +func TestUpdateCustomCacheCmd(t *testing.T) { + var out bytes.Buffer + rootDir := ensure.TempDir(t) + cachePath := filepath.Join(rootDir, "updcustomcache") + _ = os.Mkdir(cachePath, os.ModePerm) + defer os.RemoveAll(cachePath) + o := &repoUpdateOptions{ + update: updateCharts, + repoFile: "testdata/repositories.yaml", + repoCache: cachePath, + } + if err := o.run(&out); err != nil { + t.Fatal(err) + } + if _, err := os.Stat(filepath.Join(cachePath, "charts-index.yaml")); err != nil { + t.Fatalf("error finding created index file in custom cache: %#v", err) + } +} + func TestUpdateCharts(t *testing.T) { defer resetEnv()() defer ensure.HelmHome(t)() @@ -81,34 +100,3 @@ func TestUpdateCharts(t *testing.T) { t.Error("Update was not successful") } } - -func TestUpdateChartsCustomCache(t *testing.T) { - defer resetEnv()() - defer ensure.HelmHome(t)() - - ts, err := repotest.NewTempServer("testdata/testserver/*.*") - if err != nil { - t.Fatal(err) - } - defer ts.Stop() - - r, err := repo.NewChartRepository(&repo.Entry{ - Name: "charts", - URL: ts.URL(), - }, getter.All(settings)) - if err != nil { - t.Error(err) - } - - cachePath := ensure.TempDir(t) - cacheFile := filepath.Join(cachePath, "charts-index.yaml") - r.CachePath = cachePath - - b := bytes.NewBuffer(nil) - updateCharts([]*repo.ChartRepository{r}, b) - - _, err = ioutil.ReadFile(cacheFile) - if err != nil { - t.Error(err) - } -} From 146e0f9cc3b9c7ca9cb9dd0eba12de2270ae6faf Mon Sep 17 00:00:00 2001 From: hzliangbin Date: Thu, 21 May 2020 18:00:16 +0800 Subject: [PATCH 35/66] add kind_sorter support for SecretList Signed-off-by: Bin Liang --- pkg/releaseutil/kind_sorter.go | 2 ++ pkg/releaseutil/kind_sorter_test.go | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/pkg/releaseutil/kind_sorter.go b/pkg/releaseutil/kind_sorter.go index 5b131b3b0..a340dfc29 100644 --- a/pkg/releaseutil/kind_sorter.go +++ b/pkg/releaseutil/kind_sorter.go @@ -37,6 +37,7 @@ var InstallOrder KindSortOrder = []string{ "PodDisruptionBudget", "ServiceAccount", "Secret", + "SecretList", "ConfigMap", "StorageClass", "PersistentVolume", @@ -93,6 +94,7 @@ var UninstallOrder KindSortOrder = []string{ "PersistentVolume", "StorageClass", "ConfigMap", + "SecretList", "Secret", "ServiceAccount", "PodDisruptionBudget", diff --git a/pkg/releaseutil/kind_sorter_test.go b/pkg/releaseutil/kind_sorter_test.go index 341f528a0..71d355210 100644 --- a/pkg/releaseutil/kind_sorter_test.go +++ b/pkg/releaseutil/kind_sorter_test.go @@ -25,6 +25,10 @@ import ( func TestKindSorter(t *testing.T) { manifests := []Manifest{ + { + Name: "E", + Head: &SimpleHead{Kind: "SecretList"}, + }, { Name: "i", Head: &SimpleHead{Kind: "ClusterRole"}, @@ -168,8 +172,8 @@ func TestKindSorter(t *testing.T) { order KindSortOrder expected string }{ - {"install", InstallOrder, "aAbcC3def1gh2iIjJkKlLmnopqrxstuvw!"}, - {"uninstall", UninstallOrder, "wvmutsxrqponLlKkJjIi2hg1fed3CcbAa!"}, + {"install", InstallOrder, "aAbcC3deEf1gh2iIjJkKlLmnopqrxstuvw!"}, + {"uninstall", UninstallOrder, "wvmutsxrqponLlKkJjIi2hg1fEed3CcbAa!"}, } { var buf bytes.Buffer t.Run(test.description, func(t *testing.T) { From 6d49f562bce78c6459f11e82ea8d37e12edb8590 Mon Sep 17 00:00:00 2001 From: vitt-bagal <31851690+vitt-bagal@users.noreply.github.com> Date: Wed, 20 May 2020 19:00:17 +0530 Subject: [PATCH 36/66] Added s390x support Signed-off-by: vitthalb@us.ibm.com --- scripts/get-helm-3 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/get-helm-3 b/scripts/get-helm-3 index 1d0b3502e..22a93aa0e 100755 --- a/scripts/get-helm-3 +++ b/scripts/get-helm-3 @@ -33,6 +33,7 @@ initArch() { x86_64) ARCH="amd64";; i686) ARCH="386";; i386) ARCH="386";; + s390x) ARCH="s390x";; esac } @@ -60,7 +61,7 @@ runAsRoot() { # verifySupported checks that the os/arch combination is supported for # binary builds. verifySupported() { - local supported="darwin-386\ndarwin-amd64\nlinux-386\nlinux-amd64\nlinux-arm\nlinux-arm64\nlinux-ppc64le\nwindows-386\nwindows-amd64" + local supported="darwin-386\ndarwin-amd64\nlinux-386\nlinux-amd64\nlinux-arm\nlinux-arm64\nlinux-ppc64le\nlinux-s390x\nwindows-386\nwindows-amd64" if ! echo "${supported}" | grep -q "${OS}-${ARCH}"; then echo "No prebuilt binary for ${OS}-${ARCH}." echo "To build from source, go to https://github.com/helm/helm" From dbd001e5326561076e17a62b41ea3a9aa18e069d Mon Sep 17 00:00:00 2001 From: Matt Farina Date: Thu, 21 May 2020 15:26:16 -0400 Subject: [PATCH 37/66] Removing tiller language Since Tiller is no longer part of Helm v3, internal documentation language about Tiller can be removed Signed-off-by: Matt Farina --- pkg/engine/doc.go | 8 ++++---- pkg/engine/engine.go | 2 +- pkg/kube/client.go | 2 +- pkg/lint/rules/template.go | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pkg/engine/doc.go b/pkg/engine/doc.go index a68b6f7af..6ff875c46 100644 --- a/pkg/engine/doc.go +++ b/pkg/engine/doc.go @@ -14,10 +14,10 @@ See the License for the specific language governing permissions and limitations under the License. */ -/*Package engine implements the Go template engine as a Tiller Engine. +/*Package engine implements the Go text template engine as needed for Helm. -Tiller provides a simple interface for taking a Chart and rendering its templates. -The 'engine' package implements this interface using Go's built-in 'text/template' -package. +When Helm renders templates it does so with additional functions and different +modes (e.g., strict, lint mode). This package handles the helm specific +implementation. */ package engine // import "helm.sh/helm/v3/pkg/engine" diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index c5d064ad5..5aa0ed8ec 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -33,7 +33,7 @@ import ( "helm.sh/helm/v3/pkg/chartutil" ) -// Engine is an implementation of 'cmd/tiller/environment'.Engine that uses Go templates. +// Engine is an implementation of the Helm rendering implementation for templates. type Engine struct { // If strict is enabled, template rendering will fail if a template references // a value that was not passed in. diff --git a/pkg/kube/client.go b/pkg/kube/client.go index 4683d8033..f908611db 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -434,7 +434,7 @@ func updateResource(c *Client, target *resource.Info, currentObj runtime.Object, if patch == nil || string(patch) == "{}" { c.Log("Looks like there are no changes for %s %q", target.Mapping.GroupVersionKind.Kind, target.Name) - // This needs to happen to make sure that tiller has the latest info from the API + // This needs to happen to make sure that Helm has the latest info from the API // Otherwise there will be no labels and other functions that use labels will panic if err := target.Get(); err != nil { return errors.Wrap(err, "failed to refresh resource information") diff --git a/pkg/lint/rules/template.go b/pkg/lint/rules/template.go index 787c5b26a..cf8b4f84b 100644 --- a/pkg/lint/rules/template.go +++ b/pkg/lint/rules/template.go @@ -57,7 +57,7 @@ func Templates(linter *support.Linter, values map[string]interface{}, namespace return } - // Load chart and parse templates, based on tiller/release_server + // Load chart and parse templates chart, err := loader.Load(linter.ChartDir) chartLoaded := linter.RunLinterRule(support.ErrorSev, path, err) From 99f277a2f3de395160b473ac7a8cae6c380b6d1c Mon Sep 17 00:00:00 2001 From: Matt Farina Date: Fri, 22 May 2020 09:51:48 -0400 Subject: [PATCH 38/66] Using flags instead of persistent flags on status Persistent flags are available on subcommands. Status does not need the persistent nature. Closes #8149 Signed-off-by: Matt Farina --- cmd/helm/status.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/helm/status.go b/cmd/helm/status.go index 6313b3975..2efb2006c 100644 --- a/cmd/helm/status.go +++ b/cmd/helm/status.go @@ -74,7 +74,7 @@ func newStatusCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { return compListReleases(toComplete, cfg) }) - f := cmd.PersistentFlags() + f := cmd.Flags() f.IntVar(&client.Version, "revision", 0, "if set, display the status of the named release with revision") flag := f.Lookup("revision") From c56778a8d8c7fe3237bb38f6019d7003d85603d0 Mon Sep 17 00:00:00 2001 From: Matt Farina Date: Fri, 22 May 2020 11:43:32 -0400 Subject: [PATCH 39/66] Removing legacy completions.bash file This file was previously used for shell completions but is no longer in use as there is a new completions system in place and there has been for some time. The contents of this file were out of date and reflect Helm v2. Closes #8186 Signed-off-by: Matt Farina --- scripts/completions.bash | 1632 -------------------------------------- 1 file changed, 1632 deletions(-) delete mode 100644 scripts/completions.bash diff --git a/scripts/completions.bash b/scripts/completions.bash deleted file mode 100644 index 027cc3322..000000000 --- a/scripts/completions.bash +++ /dev/null @@ -1,1632 +0,0 @@ -# bash completion for helm -*- shell-script -*- - -__debug() -{ - if [[ -n ${BASH_COMP_DEBUG_FILE} ]]; then - echo "$*" >> "${BASH_COMP_DEBUG_FILE}" - fi -} - -# Homebrew on Macs have version 1.3 of bash-completion which doesn't include -# _init_completion. This is a very minimal version of that function. -__my_init_completion() -{ - COMPREPLY=() - _get_comp_words_by_ref "$@" cur prev words cword -} - -__index_of_word() -{ - local w word=$1 - shift - index=0 - for w in "$@"; do - [[ $w = "$word" ]] && return - index=$((index+1)) - done - index=-1 -} - -__contains_word() -{ - local w word=$1; shift - for w in "$@"; do - [[ $w = "$word" ]] && return - done - return 1 -} - -__handle_reply() -{ - __debug "${FUNCNAME[0]}" - case $cur in - -*) - if [[ $(type -t compopt) = "builtin" ]]; then - compopt -o nospace - fi - local allflags - if [ ${#must_have_one_flag[@]} -ne 0 ]; then - allflags=("${must_have_one_flag[@]}") - else - allflags=("${flags[*]} ${two_word_flags[*]}") - fi - COMPREPLY=( $(compgen -W "${allflags[*]}" -- "$cur") ) - if [[ $(type -t compopt) = "builtin" ]]; then - [[ "${COMPREPLY[0]}" == *= ]] || compopt +o nospace - fi - - # complete after --flag=abc - if [[ $cur == *=* ]]; then - if [[ $(type -t compopt) = "builtin" ]]; then - compopt +o nospace - fi - - local index flag - flag="${cur%%=*}" - __index_of_word "${flag}" "${flags_with_completion[@]}" - if [[ ${index} -ge 0 ]]; then - COMPREPLY=() - PREFIX="" - cur="${cur#*=}" - ${flags_completion[${index}]} - if [ -n "${ZSH_VERSION}" ]; then - # zfs completion needs --flag= prefix - eval "COMPREPLY=( \"\${COMPREPLY[@]/#/${flag}=}\" )" - fi - fi - fi - return 0; - ;; - esac - - # check if we are handling a flag with special work handling - local index - __index_of_word "${prev}" "${flags_with_completion[@]}" - if [[ ${index} -ge 0 ]]; then - ${flags_completion[${index}]} - return - fi - - # we are parsing a flag and don't have a special handler, no completion - if [[ ${cur} != "${words[cword]}" ]]; then - return - fi - - local completions - completions=("${commands[@]}") - if [[ ${#must_have_one_noun[@]} -ne 0 ]]; then - completions=("${must_have_one_noun[@]}") - fi - if [[ ${#must_have_one_flag[@]} -ne 0 ]]; then - completions+=("${must_have_one_flag[@]}") - fi - COMPREPLY=( $(compgen -W "${completions[*]}" -- "$cur") ) - - if [[ ${#COMPREPLY[@]} -eq 0 && ${#noun_aliases[@]} -gt 0 && ${#must_have_one_noun[@]} -ne 0 ]]; then - COMPREPLY=( $(compgen -W "${noun_aliases[*]}" -- "$cur") ) - fi - - if [[ ${#COMPREPLY[@]} -eq 0 ]]; then - declare -F __custom_func >/dev/null && __custom_func - fi - - __ltrim_colon_completions "$cur" -} - -# The arguments should be in the form "ext1|ext2|extn" -__handle_filename_extension_flag() -{ - local ext="$1" - _filedir "@(${ext})" -} - -__handle_subdirs_in_dir_flag() -{ - local dir="$1" - pushd "${dir}" >/dev/null 2>&1 && _filedir -d && popd >/dev/null 2>&1 -} - -__handle_flag() -{ - __debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}" - - # if a command required a flag, and we found it, unset must_have_one_flag() - local flagname=${words[c]} - local flagvalue - # if the word contained an = - if [[ ${words[c]} == *"="* ]]; then - flagvalue=${flagname#*=} # take in as flagvalue after the = - flagname=${flagname%%=*} # strip everything after the = - flagname="${flagname}=" # but put the = back - fi - __debug "${FUNCNAME[0]}: looking for ${flagname}" - if __contains_word "${flagname}" "${must_have_one_flag[@]}"; then - must_have_one_flag=() - fi - - # if you set a flag which only applies to this command, don't show subcommands - if __contains_word "${flagname}" "${local_nonpersistent_flags[@]}"; then - commands=() - fi - - # keep flag value with flagname as flaghash - if [ -n "${flagvalue}" ] ; then - flaghash[${flagname}]=${flagvalue} - elif [ -n "${words[ $((c+1)) ]}" ] ; then - flaghash[${flagname}]=${words[ $((c+1)) ]} - else - flaghash[${flagname}]="true" # pad "true" for bool flag - fi - - # skip the argument to a two word flag - if __contains_word "${words[c]}" "${two_word_flags[@]}"; then - c=$((c+1)) - # if we are looking for a flags value, don't show commands - if [[ $c -eq $cword ]]; then - commands=() - fi - fi - - c=$((c+1)) - -} - -__handle_noun() -{ - __debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}" - - if __contains_word "${words[c]}" "${must_have_one_noun[@]}"; then - must_have_one_noun=() - elif __contains_word "${words[c]}" "${noun_aliases[@]}"; then - must_have_one_noun=() - fi - - nouns+=("${words[c]}") - c=$((c+1)) -} - -__handle_command() -{ - __debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}" - - local next_command - if [[ -n ${last_command} ]]; then - next_command="_${last_command}_${words[c]//:/__}" - else - if [[ $c -eq 0 ]]; then - next_command="_$(basename "${words[c]//:/__}")" - else - next_command="_${words[c]//:/__}" - fi - fi - c=$((c+1)) - __debug "${FUNCNAME[0]}: looking for ${next_command}" - declare -F $next_command >/dev/null && $next_command -} - -__handle_word() -{ - if [[ $c -ge $cword ]]; then - __handle_reply - return - fi - __debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}" - if [[ "${words[c]}" == -* ]]; then - __handle_flag - elif __contains_word "${words[c]}" "${commands[@]}"; then - __handle_command - elif [[ $c -eq 0 ]] && __contains_word "$(basename "${words[c]}")" "${commands[@]}"; then - __handle_command - else - __handle_noun - fi - __handle_word -} - -_helm_completion() -{ - last_command="helm_completion" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - must_have_one_noun+=("bash") - must_have_one_noun+=("zsh") - noun_aliases=() -} - -_helm_create() -{ - last_command="helm_create" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--starter=") - two_word_flags+=("-p") - local_nonpersistent_flags+=("--starter=") - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_delete() -{ - last_command="helm_delete" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--dry-run") - local_nonpersistent_flags+=("--dry-run") - flags+=("--no-hooks") - local_nonpersistent_flags+=("--no-hooks") - flags+=("--keep-history") - local_nonpersistent_flags+=("--keep-history") - flags+=("--timeout=") - local_nonpersistent_flags+=("--timeout=") - flags+=("--tls") - local_nonpersistent_flags+=("--tls") - flags+=("--tls-ca-cert=") - local_nonpersistent_flags+=("--tls-ca-cert=") - flags+=("--tls-cert=") - local_nonpersistent_flags+=("--tls-cert=") - flags+=("--tls-key=") - local_nonpersistent_flags+=("--tls-key=") - flags+=("--tls-verify") - local_nonpersistent_flags+=("--tls-verify") - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_dependency_build() -{ - last_command="helm_dependency_build" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--keyring=") - local_nonpersistent_flags+=("--keyring=") - flags+=("--verify") - local_nonpersistent_flags+=("--verify") - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_dependency_list() -{ - last_command="helm_dependency_list" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_dependency_update() -{ - last_command="helm_dependency_update" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--keyring=") - local_nonpersistent_flags+=("--keyring=") - flags+=("--skip-refresh") - local_nonpersistent_flags+=("--skip-refresh") - flags+=("--verify") - local_nonpersistent_flags+=("--verify") - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_dependency() -{ - last_command="helm_dependency" - commands=() - commands+=("build") - commands+=("list") - commands+=("update") - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_fetch() -{ - last_command="helm_fetch" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--ca-file=") - local_nonpersistent_flags+=("--ca-file=") - flags+=("--cert-file=") - local_nonpersistent_flags+=("--cert-file=") - flags+=("--destination=") - two_word_flags+=("-d") - local_nonpersistent_flags+=("--destination=") - flags+=("--devel") - local_nonpersistent_flags+=("--devel") - flags+=("--key-file=") - local_nonpersistent_flags+=("--key-file=") - flags+=("--keyring=") - local_nonpersistent_flags+=("--keyring=") - flags+=("--prov") - local_nonpersistent_flags+=("--prov") - flags+=("--repo=") - local_nonpersistent_flags+=("--repo=") - flags+=("--untar") - local_nonpersistent_flags+=("--untar") - flags+=("--untardir=") - local_nonpersistent_flags+=("--untardir=") - flags+=("--verify") - local_nonpersistent_flags+=("--verify") - flags+=("--version=") - local_nonpersistent_flags+=("--version=") - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_get_hooks() -{ - last_command="helm_get_hooks" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--revision=") - local_nonpersistent_flags+=("--revision=") - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_get_manifest() -{ - last_command="helm_get_manifest" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--revision=") - local_nonpersistent_flags+=("--revision=") - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_get_values() -{ - last_command="helm_get_values" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--all") - flags+=("-a") - local_nonpersistent_flags+=("--all") - flags+=("--revision=") - local_nonpersistent_flags+=("--revision=") - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_get() -{ - last_command="helm_get" - commands=() - commands+=("hooks") - commands+=("manifest") - commands+=("values") - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--revision=") - local_nonpersistent_flags+=("--revision=") - flags+=("--tls") - local_nonpersistent_flags+=("--tls") - flags+=("--tls-ca-cert=") - local_nonpersistent_flags+=("--tls-ca-cert=") - flags+=("--tls-cert=") - local_nonpersistent_flags+=("--tls-cert=") - flags+=("--tls-key=") - local_nonpersistent_flags+=("--tls-key=") - flags+=("--tls-verify") - local_nonpersistent_flags+=("--tls-verify") - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_history() -{ - last_command="helm_history" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--max=") - local_nonpersistent_flags+=("--max=") - flags+=("--tls") - local_nonpersistent_flags+=("--tls") - flags+=("--tls-ca-cert=") - local_nonpersistent_flags+=("--tls-ca-cert=") - flags+=("--tls-cert=") - local_nonpersistent_flags+=("--tls-cert=") - flags+=("--tls-key=") - local_nonpersistent_flags+=("--tls-key=") - flags+=("--tls-verify") - local_nonpersistent_flags+=("--tls-verify") - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_home() -{ - last_command="helm_home" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_init() -{ - last_command="helm_init" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--canary-image") - local_nonpersistent_flags+=("--canary-image") - flags+=("--client-only") - flags+=("-c") - local_nonpersistent_flags+=("--client-only") - flags+=("--dry-run") - local_nonpersistent_flags+=("--dry-run") - flags+=("--local-repo-url=") - local_nonpersistent_flags+=("--local-repo-url=") - flags+=("--net-host") - local_nonpersistent_flags+=("--net-host") - flags+=("--service-account=") - local_nonpersistent_flags+=("--service-account=") - flags+=("--skip-refresh") - local_nonpersistent_flags+=("--skip-refresh") - flags+=("--tiller-image=") - two_word_flags+=("-i") - local_nonpersistent_flags+=("--tiller-image=") - flags+=("--tiller-tls") - local_nonpersistent_flags+=("--tiller-tls") - flags+=("--tiller-tls-cert=") - local_nonpersistent_flags+=("--tiller-tls-cert=") - flags+=("--tiller-tls-key=") - local_nonpersistent_flags+=("--tiller-tls-key=") - flags+=("--tiller-tls-verify") - local_nonpersistent_flags+=("--tiller-tls-verify") - flags+=("--tls-ca-cert=") - local_nonpersistent_flags+=("--tls-ca-cert=") - flags+=("--upgrade") - local_nonpersistent_flags+=("--upgrade") - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_inspect_chart() -{ - last_command="helm_inspect_chart" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--ca-file=") - local_nonpersistent_flags+=("--ca-file=") - flags+=("--cert-file=") - local_nonpersistent_flags+=("--cert-file=") - flags+=("--key-file=") - local_nonpersistent_flags+=("--key-file=") - flags+=("--keyring=") - local_nonpersistent_flags+=("--keyring=") - flags+=("--repo=") - local_nonpersistent_flags+=("--repo=") - flags+=("--verify") - local_nonpersistent_flags+=("--verify") - flags+=("--version=") - local_nonpersistent_flags+=("--version=") - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_inspect_values() -{ - last_command="helm_inspect_values" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--ca-file=") - local_nonpersistent_flags+=("--ca-file=") - flags+=("--cert-file=") - local_nonpersistent_flags+=("--cert-file=") - flags+=("--key-file=") - local_nonpersistent_flags+=("--key-file=") - flags+=("--keyring=") - local_nonpersistent_flags+=("--keyring=") - flags+=("--repo=") - local_nonpersistent_flags+=("--repo=") - flags+=("--verify") - local_nonpersistent_flags+=("--verify") - flags+=("--version=") - local_nonpersistent_flags+=("--version=") - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_inspect() -{ - last_command="helm_inspect" - commands=() - commands+=("chart") - commands+=("values") - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--ca-file=") - local_nonpersistent_flags+=("--ca-file=") - flags+=("--cert-file=") - local_nonpersistent_flags+=("--cert-file=") - flags+=("--key-file=") - local_nonpersistent_flags+=("--key-file=") - flags+=("--keyring=") - local_nonpersistent_flags+=("--keyring=") - flags+=("--repo=") - local_nonpersistent_flags+=("--repo=") - flags+=("--verify") - local_nonpersistent_flags+=("--verify") - flags+=("--version=") - local_nonpersistent_flags+=("--version=") - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_install() -{ - last_command="helm_install" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--ca-file=") - local_nonpersistent_flags+=("--ca-file=") - flags+=("--cert-file=") - local_nonpersistent_flags+=("--cert-file=") - flags+=("--devel") - local_nonpersistent_flags+=("--devel") - flags+=("--dry-run") - local_nonpersistent_flags+=("--dry-run") - flags+=("--key-file=") - local_nonpersistent_flags+=("--key-file=") - flags+=("--keyring=") - local_nonpersistent_flags+=("--keyring=") - flags+=("--name=") - two_word_flags+=("-n") - local_nonpersistent_flags+=("--name=") - flags+=("--name-template=") - local_nonpersistent_flags+=("--name-template=") - flags+=("--namespace=") - local_nonpersistent_flags+=("--namespace=") - flags+=("--no-hooks") - local_nonpersistent_flags+=("--no-hooks") - flags+=("--replace") - local_nonpersistent_flags+=("--replace") - flags+=("--repo=") - local_nonpersistent_flags+=("--repo=") - flags+=("--set=") - local_nonpersistent_flags+=("--set=") - flags+=("--set-string=") - local_nonpersistent_flags+=("--set-string=") - flags+=("--timeout=") - local_nonpersistent_flags+=("--timeout=") - flags+=("--tls") - local_nonpersistent_flags+=("--tls") - flags+=("--tls-ca-cert=") - local_nonpersistent_flags+=("--tls-ca-cert=") - flags+=("--tls-cert=") - local_nonpersistent_flags+=("--tls-cert=") - flags+=("--tls-key=") - local_nonpersistent_flags+=("--tls-key=") - flags+=("--tls-verify") - local_nonpersistent_flags+=("--tls-verify") - flags+=("--values=") - two_word_flags+=("-f") - local_nonpersistent_flags+=("--values=") - flags+=("--verify") - local_nonpersistent_flags+=("--verify") - flags+=("--version=") - local_nonpersistent_flags+=("--version=") - flags+=("--wait") - local_nonpersistent_flags+=("--wait") - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_lint() -{ - last_command="helm_lint" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--strict") - local_nonpersistent_flags+=("--strict") - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_list() -{ - last_command="helm_list" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--all") - local_nonpersistent_flags+=("--all") - flags+=("--date") - flags+=("-d") - local_nonpersistent_flags+=("--date") - flags+=("--uninstalled") - local_nonpersistent_flags+=("--uninstalled") - flags+=("--uninstalling") - local_nonpersistent_flags+=("--uninstalling") - flags+=("--deployed") - local_nonpersistent_flags+=("--deployed") - flags+=("--failed") - local_nonpersistent_flags+=("--failed") - flags+=("--max=") - two_word_flags+=("-m") - local_nonpersistent_flags+=("--max=") - flags+=("--namespace=") - local_nonpersistent_flags+=("--namespace=") - flags+=("--offset=") - two_word_flags+=("-o") - local_nonpersistent_flags+=("--offset=") - flags+=("--reverse") - flags+=("-r") - local_nonpersistent_flags+=("--reverse") - flags+=("--short") - flags+=("-q") - local_nonpersistent_flags+=("--short") - flags+=("--tls") - local_nonpersistent_flags+=("--tls") - flags+=("--tls-ca-cert=") - local_nonpersistent_flags+=("--tls-ca-cert=") - flags+=("--tls-cert=") - local_nonpersistent_flags+=("--tls-cert=") - flags+=("--tls-key=") - local_nonpersistent_flags+=("--tls-key=") - flags+=("--tls-verify") - local_nonpersistent_flags+=("--tls-verify") - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_package() -{ - last_command="helm_package" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--destination=") - two_word_flags+=("-d") - local_nonpersistent_flags+=("--destination=") - flags+=("--key=") - local_nonpersistent_flags+=("--key=") - flags+=("--keyring=") - local_nonpersistent_flags+=("--keyring=") - flags+=("--save") - local_nonpersistent_flags+=("--save") - flags+=("--sign") - local_nonpersistent_flags+=("--sign") - flags+=("--version=") - local_nonpersistent_flags+=("--version=") - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_plugin_install() -{ - last_command="helm_plugin_install" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--version=") - local_nonpersistent_flags+=("--version=") - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_plugin_list() -{ - last_command="helm_plugin_list" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_plugin_remove() -{ - last_command="helm_plugin_remove" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_plugin_update() -{ - last_command="helm_plugin_update" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_plugin() -{ - last_command="helm_plugin" - commands=() - commands+=("install") - commands+=("list") - commands+=("remove") - commands+=("update") - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_repo_add() -{ - last_command="helm_repo_add" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--ca-file=") - local_nonpersistent_flags+=("--ca-file=") - flags+=("--cert-file=") - local_nonpersistent_flags+=("--cert-file=") - flags+=("--key-file=") - local_nonpersistent_flags+=("--key-file=") - flags+=("--no-update") - local_nonpersistent_flags+=("--no-update") - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_repo_index() -{ - last_command="helm_repo_index" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--merge=") - local_nonpersistent_flags+=("--merge=") - flags+=("--url=") - local_nonpersistent_flags+=("--url=") - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_repo_list() -{ - last_command="helm_repo_list" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_repo_remove() -{ - last_command="helm_repo_remove" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_repo_update() -{ - last_command="helm_repo_update" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_repo() -{ - last_command="helm_repo" - commands=() - commands+=("add") - commands+=("index") - commands+=("list") - commands+=("remove") - commands+=("update") - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_reset() -{ - last_command="helm_reset" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--force") - flags+=("-f") - local_nonpersistent_flags+=("--force") - flags+=("--remove-helm-home") - local_nonpersistent_flags+=("--remove-helm-home") - flags+=("--tls") - local_nonpersistent_flags+=("--tls") - flags+=("--tls-ca-cert=") - local_nonpersistent_flags+=("--tls-ca-cert=") - flags+=("--tls-cert=") - local_nonpersistent_flags+=("--tls-cert=") - flags+=("--tls-key=") - local_nonpersistent_flags+=("--tls-key=") - flags+=("--tls-verify") - local_nonpersistent_flags+=("--tls-verify") - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_rollback() -{ - last_command="helm_rollback" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--dry-run") - local_nonpersistent_flags+=("--dry-run") - flags+=("--force") - local_nonpersistent_flags+=("--force") - flags+=("--no-hooks") - local_nonpersistent_flags+=("--no-hooks") - flags+=("--recreate-pods") - local_nonpersistent_flags+=("--recreate-pods") - flags+=("--timeout=") - local_nonpersistent_flags+=("--timeout=") - flags+=("--tls") - local_nonpersistent_flags+=("--tls") - flags+=("--tls-ca-cert=") - local_nonpersistent_flags+=("--tls-ca-cert=") - flags+=("--tls-cert=") - local_nonpersistent_flags+=("--tls-cert=") - flags+=("--tls-key=") - local_nonpersistent_flags+=("--tls-key=") - flags+=("--tls-verify") - local_nonpersistent_flags+=("--tls-verify") - flags+=("--wait") - local_nonpersistent_flags+=("--wait") - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_search() -{ - last_command="helm_search" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--regexp") - flags+=("-r") - local_nonpersistent_flags+=("--regexp") - flags+=("--version=") - two_word_flags+=("-v") - local_nonpersistent_flags+=("--version=") - flags+=("--versions") - flags+=("-l") - local_nonpersistent_flags+=("--versions") - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_serve() -{ - last_command="helm_serve" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--address=") - local_nonpersistent_flags+=("--address=") - flags+=("--repo-path=") - local_nonpersistent_flags+=("--repo-path=") - flags+=("--url=") - local_nonpersistent_flags+=("--url=") - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_status() -{ - last_command="helm_status" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--revision=") - flags+=("--tls") - local_nonpersistent_flags+=("--tls") - flags+=("--tls-ca-cert=") - local_nonpersistent_flags+=("--tls-ca-cert=") - flags+=("--tls-cert=") - local_nonpersistent_flags+=("--tls-cert=") - flags+=("--tls-key=") - local_nonpersistent_flags+=("--tls-key=") - flags+=("--tls-verify") - local_nonpersistent_flags+=("--tls-verify") - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_test() -{ - last_command="helm_test" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--cleanup") - local_nonpersistent_flags+=("--cleanup") - flags+=("--timeout=") - local_nonpersistent_flags+=("--timeout=") - flags+=("--tls") - local_nonpersistent_flags+=("--tls") - flags+=("--tls-ca-cert=") - local_nonpersistent_flags+=("--tls-ca-cert=") - flags+=("--tls-cert=") - local_nonpersistent_flags+=("--tls-cert=") - flags+=("--tls-key=") - local_nonpersistent_flags+=("--tls-key=") - flags+=("--tls-verify") - local_nonpersistent_flags+=("--tls-verify") - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_upgrade() -{ - last_command="helm_upgrade" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--ca-file=") - local_nonpersistent_flags+=("--ca-file=") - flags+=("--cert-file=") - local_nonpersistent_flags+=("--cert-file=") - flags+=("--devel") - local_nonpersistent_flags+=("--devel") - flags+=("--disable-hooks") - local_nonpersistent_flags+=("--disable-hooks") - flags+=("--dry-run") - local_nonpersistent_flags+=("--dry-run") - flags+=("--force") - local_nonpersistent_flags+=("--force") - flags+=("--install") - flags+=("-i") - local_nonpersistent_flags+=("--install") - flags+=("--key-file=") - local_nonpersistent_flags+=("--key-file=") - flags+=("--keyring=") - local_nonpersistent_flags+=("--keyring=") - flags+=("--namespace=") - local_nonpersistent_flags+=("--namespace=") - flags+=("--no-hooks") - local_nonpersistent_flags+=("--no-hooks") - flags+=("--recreate-pods") - local_nonpersistent_flags+=("--recreate-pods") - flags+=("--repo=") - local_nonpersistent_flags+=("--repo=") - flags+=("--reset-values") - local_nonpersistent_flags+=("--reset-values") - flags+=("--reuse-values") - local_nonpersistent_flags+=("--reuse-values") - flags+=("--set=") - local_nonpersistent_flags+=("--set=") - flags+=("--timeout=") - local_nonpersistent_flags+=("--timeout=") - flags+=("--tls") - local_nonpersistent_flags+=("--tls") - flags+=("--tls-ca-cert=") - local_nonpersistent_flags+=("--tls-ca-cert=") - flags+=("--tls-cert=") - local_nonpersistent_flags+=("--tls-cert=") - flags+=("--tls-key=") - local_nonpersistent_flags+=("--tls-key=") - flags+=("--tls-verify") - local_nonpersistent_flags+=("--tls-verify") - flags+=("--values=") - two_word_flags+=("-f") - local_nonpersistent_flags+=("--values=") - flags+=("--verify") - local_nonpersistent_flags+=("--verify") - flags+=("--version=") - local_nonpersistent_flags+=("--version=") - flags+=("--wait") - local_nonpersistent_flags+=("--wait") - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_verify() -{ - last_command="helm_verify" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--keyring=") - local_nonpersistent_flags+=("--keyring=") - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm_version() -{ - last_command="helm_version" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--client") - flags+=("-c") - local_nonpersistent_flags+=("--client") - flags+=("--server") - flags+=("-s") - local_nonpersistent_flags+=("--server") - flags+=("--short") - local_nonpersistent_flags+=("--short") - flags+=("--tls") - local_nonpersistent_flags+=("--tls") - flags+=("--tls-ca-cert=") - local_nonpersistent_flags+=("--tls-ca-cert=") - flags+=("--tls-cert=") - local_nonpersistent_flags+=("--tls-cert=") - flags+=("--tls-key=") - local_nonpersistent_flags+=("--tls-key=") - flags+=("--tls-verify") - local_nonpersistent_flags+=("--tls-verify") - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_helm() -{ - last_command="helm" - commands=() - commands+=("completion") - commands+=("create") - commands+=("delete") - commands+=("dependency") - commands+=("fetch") - commands+=("get") - commands+=("history") - commands+=("home") - commands+=("init") - commands+=("inspect") - commands+=("install") - commands+=("lint") - commands+=("list") - commands+=("package") - commands+=("plugin") - commands+=("repo") - commands+=("reset") - commands+=("rollback") - commands+=("search") - commands+=("serve") - commands+=("status") - commands+=("test") - commands+=("upgrade") - commands+=("verify") - commands+=("version") - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--debug") - flags+=("--host=") - flags+=("--kube-context=") - flags+=("--tiller-namespace=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -__start_helm() -{ - local cur prev words cword - declare -A flaghash 2>/dev/null || : - if declare -F _init_completion >/dev/null 2>&1; then - _init_completion -s || return - else - __my_init_completion -n "=" || return - fi - - local c=0 - local flags=() - local two_word_flags=() - local local_nonpersistent_flags=() - local flags_with_completion=() - local flags_completion=() - local commands=("helm") - local must_have_one_flag=() - local must_have_one_noun=() - local last_command - local nouns=() - - __handle_word -} - -if [[ $(type -t compopt) = "builtin" ]]; then - complete -o default -F __start_helm helm -else - complete -o default -o nospace -F __start_helm helm -fi - -# ex: ts=4 sw=4 et filetype=sh From f182ebc11c9ea7a5bf75e35d8e061f3ac68482fd Mon Sep 17 00:00:00 2001 From: Matt Farina Date: Fri, 22 May 2020 12:04:37 -0400 Subject: [PATCH 40/66] Fix issue with unhandled error on Stat If stat returns an error other than the directory not existing it was unhandled. When IsDir is called in one of these situations it causes a panic. Closes #8181 Signed-off-by: Matt Farina --- pkg/chartutil/save.go | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/pkg/chartutil/save.go b/pkg/chartutil/save.go index 1011436b5..2ce4eddaf 100644 --- a/pkg/chartutil/save.go +++ b/pkg/chartutil/save.go @@ -106,12 +106,17 @@ func Save(c *chart.Chart, outDir string) (string, error) { filename := fmt.Sprintf("%s-%s.tgz", c.Name(), c.Metadata.Version) filename = filepath.Join(outDir, filename) - if stat, err := os.Stat(filepath.Dir(filename)); os.IsNotExist(err) { - if err := os.MkdirAll(filepath.Dir(filename), 0755); err != nil { - return "", err + dir := filepath.Dir(filename) + if stat, err := os.Stat(dir); err != nil { + if os.IsNotExist(err) { + if err2 := os.MkdirAll(dir, 0755); err2 != nil { + return "", err2 + } + } else { + return "", errors.Wrapf(err, "stat %s", dir) } } else if !stat.IsDir() { - return "", errors.Errorf("is not a directory: %s", filepath.Dir(filename)) + return "", errors.Errorf("is not a directory: %s", dir) } f, err := os.Create(filename) From 44a2225035d93ab6e8dc40af7c3ee4ff13452fae Mon Sep 17 00:00:00 2001 From: Adam Reese Date: Fri, 22 May 2020 11:39:20 -0700 Subject: [PATCH 41/66] ref(tests): localize unit test fixtures to package Use test fixtures that are in the same package as test. Signed-off-by: Adam Reese --- cmd/helm/template_test.go | 2 +- .../output/template-name-template.txt | 28 +- cmd/helm/testdata/output/template-set.txt | 28 +- .../output/template-show-only-glob.txt | 12 +- .../output/template-show-only-multiple.txt | 10 +- .../output/template-show-only-one.txt | 8 +- .../testdata/output/template-values-files.txt | 28 +- .../output/template-with-api-version.txt | 28 +- .../testdata/output/template-with-crds.txt | 28 +- cmd/helm/testdata/output/template.txt | 28 +- .../chart-with-no-templates-dir/values.yaml | 1 - .../testcharts/decompressedchart/.helmignore | 5 - .../testdata/testcharts/novals/Chart.yaml | 8 - cmd/helm/testdata/testcharts/novals/README.md | 13 - .../novals/templates/alpine-pod.yaml | 28 -- .../testdata/testcharts/subchart/Chart.yaml | 36 +++ .../subchart/charts/subchartA/Chart.yaml | 4 + .../charts/subchartA/templates/service.yaml | 15 ++ .../subchart/charts/subchartA/values.yaml | 17 ++ .../subchart/charts/subchartB/Chart.yaml | 4 + .../charts/subchartB/templates/service.yaml | 15 ++ .../subchart/charts/subchartB/values.yaml | 35 +++ .../testcharts/subchart/crds/crdA.yaml | 13 + .../testcharts/subchart/templates/NOTES.txt | 1 + .../subchart/templates/service.yaml | 22 ++ .../subchart/templates/subdir/role.yaml | 7 + .../templates/subdir/rolebinding.yaml | 12 + .../templates/subdir/serviceaccount.yaml | 4 + .../testdata/testcharts/subchart/values.yaml | 55 ++++ internal/resolver/resolver_test.go | 14 +- .../testdata/chartpath/base/Chart.yaml | 3 + pkg/action/dependency_test.go | 10 +- pkg/action/lint_test.go | 26 +- pkg/action/show.go | 20 +- pkg/action/show_test.go | 61 ++--- .../charts/chart-missing-deps/.helmignore | 5 - .../charts/chart-missing-deps/Chart.yaml | 18 -- .../charts/chart-missing-deps/README.md | 232 ---------------- .../chart-missing-deps/templates/NOTES.txt | 38 --- .../chart-missing-deps/templates/_helpers.tpl | 24 -- .../charts/chart-missing-deps/values.yaml | 254 ------------------ .../.helmignore | 5 - .../Chart.yaml | 18 -- .../README.md | 3 - .../templates/NOTES.txt | 1 - .../values.yaml | 254 ------------------ .../chart-with-no-templates-dir/Chart.yaml | 0 .../chart-with-schema-negative/Chart.yaml | 7 + .../templates/empty.yaml | 1 + .../values.schema.json | 67 +++++ .../chart-with-schema-negative/values.yaml | 14 + .../charts/chart-with-schema/Chart.yaml | 7 + .../chart-with-schema/extra-values.yaml | 2 + .../chart-with-schema/templates/empty.yaml | 1 + .../chart-with-schema/values.schema.json | 67 +++++ .../charts/chart-with-schema/values.yaml | 17 ++ .../charts/compressedchart-0.1.0.tar.gz | Bin 0 -> 477 bytes .../testdata/charts/compressedchart-0.1.0.tgz | Bin 0 -> 477 bytes .../testdata/charts/compressedchart-0.2.0.tgz | Bin 0 -> 477 bytes .../testdata/charts/compressedchart-0.3.0.tgz | Bin 0 -> 477 bytes .../compressedchart-with-hyphens-0.1.0.tgz | Bin 0 -> 548 bytes .../charts}/corrupted-compressed-chart.tgz | 0 .../charts}/decompressedchart/Chart.yaml | 0 .../charts}/decompressedchart/values.yaml | 0 .../multiplecharts-lint-chart-1/Chart.yaml | 0 .../templates/configmap.yaml | 0 .../multiplecharts-lint-chart-1/values.yaml | 0 .../multiplecharts-lint-chart-2/Chart.yaml | 0 .../templates/configmap.yaml | 0 .../multiplecharts-lint-chart-2/values.yaml | 0 .../charts/pre-release-chart-0.1.0-alpha.tgz | Bin 0 -> 355 bytes ...s-tgz.txt => list-compressed-deps-tgz.txt} | 0 ...ssed-deps.txt => list-compressed-deps.txt} | 0 ...missing-deps.txt => list-missing-deps.txt} | 0 ...tgz.txt => list-uncompressed-deps-tgz.txt} | 0 ...ed-deps.txt => list-uncompressed-deps.txt} | 0 76 files changed, 591 insertions(+), 1073 deletions(-) delete mode 100644 cmd/helm/testdata/testcharts/chart-with-no-templates-dir/values.yaml delete mode 100644 cmd/helm/testdata/testcharts/decompressedchart/.helmignore delete mode 100644 cmd/helm/testdata/testcharts/novals/Chart.yaml delete mode 100644 cmd/helm/testdata/testcharts/novals/README.md delete mode 100644 cmd/helm/testdata/testcharts/novals/templates/alpine-pod.yaml create mode 100644 cmd/helm/testdata/testcharts/subchart/Chart.yaml create mode 100644 cmd/helm/testdata/testcharts/subchart/charts/subchartA/Chart.yaml create mode 100644 cmd/helm/testdata/testcharts/subchart/charts/subchartA/templates/service.yaml create mode 100644 cmd/helm/testdata/testcharts/subchart/charts/subchartA/values.yaml create mode 100644 cmd/helm/testdata/testcharts/subchart/charts/subchartB/Chart.yaml create mode 100644 cmd/helm/testdata/testcharts/subchart/charts/subchartB/templates/service.yaml create mode 100644 cmd/helm/testdata/testcharts/subchart/charts/subchartB/values.yaml create mode 100644 cmd/helm/testdata/testcharts/subchart/crds/crdA.yaml create mode 100644 cmd/helm/testdata/testcharts/subchart/templates/NOTES.txt create mode 100644 cmd/helm/testdata/testcharts/subchart/templates/service.yaml create mode 100644 cmd/helm/testdata/testcharts/subchart/templates/subdir/role.yaml create mode 100644 cmd/helm/testdata/testcharts/subchart/templates/subdir/rolebinding.yaml create mode 100644 cmd/helm/testdata/testcharts/subchart/templates/subdir/serviceaccount.yaml create mode 100644 cmd/helm/testdata/testcharts/subchart/values.yaml create mode 100644 internal/resolver/testdata/chartpath/base/Chart.yaml delete mode 100755 pkg/action/testdata/charts/chart-missing-deps/.helmignore delete mode 100755 pkg/action/testdata/charts/chart-missing-deps/README.md delete mode 100755 pkg/action/testdata/charts/chart-missing-deps/templates/NOTES.txt delete mode 100755 pkg/action/testdata/charts/chart-missing-deps/templates/_helpers.tpl delete mode 100755 pkg/action/testdata/charts/chart-missing-deps/values.yaml delete mode 100755 pkg/action/testdata/charts/chart-with-compressed-dependencies/.helmignore delete mode 100755 pkg/action/testdata/charts/chart-with-compressed-dependencies/README.md delete mode 100755 pkg/action/testdata/charts/chart-with-compressed-dependencies/templates/NOTES.txt delete mode 100755 pkg/action/testdata/charts/chart-with-compressed-dependencies/values.yaml rename {cmd/helm/testdata/testcharts => pkg/action/testdata/charts}/chart-with-no-templates-dir/Chart.yaml (100%) create mode 100644 pkg/action/testdata/charts/chart-with-schema-negative/Chart.yaml create mode 100644 pkg/action/testdata/charts/chart-with-schema-negative/templates/empty.yaml create mode 100644 pkg/action/testdata/charts/chart-with-schema-negative/values.schema.json create mode 100644 pkg/action/testdata/charts/chart-with-schema-negative/values.yaml create mode 100644 pkg/action/testdata/charts/chart-with-schema/Chart.yaml create mode 100644 pkg/action/testdata/charts/chart-with-schema/extra-values.yaml create mode 100644 pkg/action/testdata/charts/chart-with-schema/templates/empty.yaml create mode 100644 pkg/action/testdata/charts/chart-with-schema/values.schema.json create mode 100644 pkg/action/testdata/charts/chart-with-schema/values.yaml create mode 100644 pkg/action/testdata/charts/compressedchart-0.1.0.tar.gz create mode 100644 pkg/action/testdata/charts/compressedchart-0.1.0.tgz create mode 100644 pkg/action/testdata/charts/compressedchart-0.2.0.tgz create mode 100644 pkg/action/testdata/charts/compressedchart-0.3.0.tgz create mode 100644 pkg/action/testdata/charts/compressedchart-with-hyphens-0.1.0.tgz rename {cmd/helm/testdata/testcharts => pkg/action/testdata/charts}/corrupted-compressed-chart.tgz (100%) rename {cmd/helm/testdata/testcharts => pkg/action/testdata/charts}/decompressedchart/Chart.yaml (100%) rename {cmd/helm/testdata/testcharts => pkg/action/testdata/charts}/decompressedchart/values.yaml (100%) rename {cmd/helm/testdata/testcharts => pkg/action/testdata/charts}/multiplecharts-lint-chart-1/Chart.yaml (100%) rename {cmd/helm/testdata/testcharts => pkg/action/testdata/charts}/multiplecharts-lint-chart-1/templates/configmap.yaml (100%) rename {cmd/helm/testdata/testcharts => pkg/action/testdata/charts}/multiplecharts-lint-chart-1/values.yaml (100%) rename {cmd/helm/testdata/testcharts => pkg/action/testdata/charts}/multiplecharts-lint-chart-2/Chart.yaml (100%) rename {cmd/helm/testdata/testcharts => pkg/action/testdata/charts}/multiplecharts-lint-chart-2/templates/configmap.yaml (100%) rename {cmd/helm/testdata/testcharts => pkg/action/testdata/charts}/multiplecharts-lint-chart-2/values.yaml (100%) create mode 100644 pkg/action/testdata/charts/pre-release-chart-0.1.0-alpha.tgz rename pkg/action/testdata/output/{compressed-deps-tgz.txt => list-compressed-deps-tgz.txt} (100%) rename pkg/action/testdata/output/{compressed-deps.txt => list-compressed-deps.txt} (100%) rename pkg/action/testdata/output/{missing-deps.txt => list-missing-deps.txt} (100%) rename pkg/action/testdata/output/{uncompressed-deps-tgz.txt => list-uncompressed-deps-tgz.txt} (100%) rename pkg/action/testdata/output/{uncompressed-deps.txt => list-uncompressed-deps.txt} (100%) diff --git a/cmd/helm/template_test.go b/cmd/helm/template_test.go index 87ee79e5a..92dd9825e 100644 --- a/cmd/helm/template_test.go +++ b/cmd/helm/template_test.go @@ -22,7 +22,7 @@ import ( "testing" ) -var chartPath = "./../../pkg/chartutil/testdata/subpop/charts/subchart1" +var chartPath = "testdata/testcharts/subchart" func TestTemplateCmd(t *testing.T) { tests := []cmdTestCase{ diff --git a/cmd/helm/testdata/output/template-name-template.txt b/cmd/helm/testdata/output/template-name-template.txt index 24f2bb616..84a9e565c 100644 --- a/cmd/helm/testdata/output/template-name-template.txt +++ b/cmd/helm/testdata/output/template-name-template.txt @@ -1,34 +1,34 @@ --- -# Source: subchart1/templates/subdir/serviceaccount.yaml +# Source: subchart/templates/subdir/serviceaccount.yaml apiVersion: v1 kind: ServiceAccount metadata: - name: subchart1-sa + name: subchart-sa --- -# Source: subchart1/templates/subdir/role.yaml +# Source: subchart/templates/subdir/role.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: - name: subchart1-role + name: subchart-role rules: - resources: ["*"] verbs: ["get","list","watch"] --- -# Source: subchart1/templates/subdir/rolebinding.yaml +# Source: subchart/templates/subdir/rolebinding.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: - name: subchart1-binding + name: subchart-binding roleRef: apiGroup: rbac.authorization.k8s.io kind: Role - name: subchart1-role + name: subchart-role subjects: - kind: ServiceAccount - name: subchart1-sa + name: subchart-sa namespace: default --- -# Source: subchart1/charts/subcharta/templates/service.yaml +# Source: subchart/charts/subcharta/templates/service.yaml apiVersion: v1 kind: Service metadata: @@ -45,7 +45,7 @@ spec: selector: app.kubernetes.io/name: subcharta --- -# Source: subchart1/charts/subchartb/templates/service.yaml +# Source: subchart/charts/subchartb/templates/service.yaml apiVersion: v1 kind: Service metadata: @@ -62,13 +62,13 @@ spec: selector: app.kubernetes.io/name: subchartb --- -# Source: subchart1/templates/service.yaml +# Source: subchart/templates/service.yaml apiVersion: v1 kind: Service metadata: - name: subchart1 + name: subchart labels: - helm.sh/chart: "subchart1-0.1.0" + helm.sh/chart: "subchart-0.1.0" app.kubernetes.io/instance: "foobar-YWJj-baz" kube-version/major: "1" kube-version/minor: "18" @@ -81,4 +81,4 @@ spec: protocol: TCP name: nginx selector: - app.kubernetes.io/name: subchart1 + app.kubernetes.io/name: subchart diff --git a/cmd/helm/testdata/output/template-set.txt b/cmd/helm/testdata/output/template-set.txt index 4c7f1f626..1cb97723e 100644 --- a/cmd/helm/testdata/output/template-set.txt +++ b/cmd/helm/testdata/output/template-set.txt @@ -1,34 +1,34 @@ --- -# Source: subchart1/templates/subdir/serviceaccount.yaml +# Source: subchart/templates/subdir/serviceaccount.yaml apiVersion: v1 kind: ServiceAccount metadata: - name: subchart1-sa + name: subchart-sa --- -# Source: subchart1/templates/subdir/role.yaml +# Source: subchart/templates/subdir/role.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: - name: subchart1-role + name: subchart-role rules: - resources: ["*"] verbs: ["get","list","watch"] --- -# Source: subchart1/templates/subdir/rolebinding.yaml +# Source: subchart/templates/subdir/rolebinding.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: - name: subchart1-binding + name: subchart-binding roleRef: apiGroup: rbac.authorization.k8s.io kind: Role - name: subchart1-role + name: subchart-role subjects: - kind: ServiceAccount - name: subchart1-sa + name: subchart-sa namespace: default --- -# Source: subchart1/charts/subcharta/templates/service.yaml +# Source: subchart/charts/subcharta/templates/service.yaml apiVersion: v1 kind: Service metadata: @@ -45,7 +45,7 @@ spec: selector: app.kubernetes.io/name: subcharta --- -# Source: subchart1/charts/subchartb/templates/service.yaml +# Source: subchart/charts/subchartb/templates/service.yaml apiVersion: v1 kind: Service metadata: @@ -62,13 +62,13 @@ spec: selector: app.kubernetes.io/name: subchartb --- -# Source: subchart1/templates/service.yaml +# Source: subchart/templates/service.yaml apiVersion: v1 kind: Service metadata: - name: subchart1 + name: subchart labels: - helm.sh/chart: "subchart1-0.1.0" + helm.sh/chart: "subchart-0.1.0" app.kubernetes.io/instance: "RELEASE-NAME" kube-version/major: "1" kube-version/minor: "18" @@ -81,4 +81,4 @@ spec: protocol: TCP name: apache selector: - app.kubernetes.io/name: subchart1 + app.kubernetes.io/name: subchart diff --git a/cmd/helm/testdata/output/template-show-only-glob.txt b/cmd/helm/testdata/output/template-show-only-glob.txt index 0970e6cd3..cc651f596 100644 --- a/cmd/helm/testdata/output/template-show-only-glob.txt +++ b/cmd/helm/testdata/output/template-show-only-glob.txt @@ -1,23 +1,23 @@ --- -# Source: subchart1/templates/subdir/role.yaml +# Source: subchart/templates/subdir/role.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: - name: subchart1-role + name: subchart-role rules: - resources: ["*"] verbs: ["get","list","watch"] --- -# Source: subchart1/templates/subdir/rolebinding.yaml +# Source: subchart/templates/subdir/rolebinding.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: - name: subchart1-binding + name: subchart-binding roleRef: apiGroup: rbac.authorization.k8s.io kind: Role - name: subchart1-role + name: subchart-role subjects: - kind: ServiceAccount - name: subchart1-sa + name: subchart-sa namespace: default diff --git a/cmd/helm/testdata/output/template-show-only-multiple.txt b/cmd/helm/testdata/output/template-show-only-multiple.txt index 75b590e20..1c4b1f29e 100644 --- a/cmd/helm/testdata/output/template-show-only-multiple.txt +++ b/cmd/helm/testdata/output/template-show-only-multiple.txt @@ -1,11 +1,11 @@ --- -# Source: subchart1/templates/service.yaml +# Source: subchart/templates/service.yaml apiVersion: v1 kind: Service metadata: - name: subchart1 + name: subchart labels: - helm.sh/chart: "subchart1-0.1.0" + helm.sh/chart: "subchart-0.1.0" app.kubernetes.io/instance: "RELEASE-NAME" kube-version/major: "1" kube-version/minor: "18" @@ -19,9 +19,9 @@ spec: protocol: TCP name: nginx selector: - app.kubernetes.io/name: subchart1 + app.kubernetes.io/name: subchart --- -# Source: subchart1/charts/subcharta/templates/service.yaml +# Source: subchart/charts/subcharta/templates/service.yaml apiVersion: v1 kind: Service metadata: diff --git a/cmd/helm/testdata/output/template-show-only-one.txt b/cmd/helm/testdata/output/template-show-only-one.txt index ce61f481f..7b1443ea8 100644 --- a/cmd/helm/testdata/output/template-show-only-one.txt +++ b/cmd/helm/testdata/output/template-show-only-one.txt @@ -1,11 +1,11 @@ --- -# Source: subchart1/templates/service.yaml +# Source: subchart/templates/service.yaml apiVersion: v1 kind: Service metadata: - name: subchart1 + name: subchart labels: - helm.sh/chart: "subchart1-0.1.0" + helm.sh/chart: "subchart-0.1.0" app.kubernetes.io/instance: "RELEASE-NAME" kube-version/major: "1" kube-version/minor: "18" @@ -19,4 +19,4 @@ spec: protocol: TCP name: nginx selector: - app.kubernetes.io/name: subchart1 + app.kubernetes.io/name: subchart diff --git a/cmd/helm/testdata/output/template-values-files.txt b/cmd/helm/testdata/output/template-values-files.txt index 4c7f1f626..1cb97723e 100644 --- a/cmd/helm/testdata/output/template-values-files.txt +++ b/cmd/helm/testdata/output/template-values-files.txt @@ -1,34 +1,34 @@ --- -# Source: subchart1/templates/subdir/serviceaccount.yaml +# Source: subchart/templates/subdir/serviceaccount.yaml apiVersion: v1 kind: ServiceAccount metadata: - name: subchart1-sa + name: subchart-sa --- -# Source: subchart1/templates/subdir/role.yaml +# Source: subchart/templates/subdir/role.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: - name: subchart1-role + name: subchart-role rules: - resources: ["*"] verbs: ["get","list","watch"] --- -# Source: subchart1/templates/subdir/rolebinding.yaml +# Source: subchart/templates/subdir/rolebinding.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: - name: subchart1-binding + name: subchart-binding roleRef: apiGroup: rbac.authorization.k8s.io kind: Role - name: subchart1-role + name: subchart-role subjects: - kind: ServiceAccount - name: subchart1-sa + name: subchart-sa namespace: default --- -# Source: subchart1/charts/subcharta/templates/service.yaml +# Source: subchart/charts/subcharta/templates/service.yaml apiVersion: v1 kind: Service metadata: @@ -45,7 +45,7 @@ spec: selector: app.kubernetes.io/name: subcharta --- -# Source: subchart1/charts/subchartb/templates/service.yaml +# Source: subchart/charts/subchartb/templates/service.yaml apiVersion: v1 kind: Service metadata: @@ -62,13 +62,13 @@ spec: selector: app.kubernetes.io/name: subchartb --- -# Source: subchart1/templates/service.yaml +# Source: subchart/templates/service.yaml apiVersion: v1 kind: Service metadata: - name: subchart1 + name: subchart labels: - helm.sh/chart: "subchart1-0.1.0" + helm.sh/chart: "subchart-0.1.0" app.kubernetes.io/instance: "RELEASE-NAME" kube-version/major: "1" kube-version/minor: "18" @@ -81,4 +81,4 @@ spec: protocol: TCP name: apache selector: - app.kubernetes.io/name: subchart1 + app.kubernetes.io/name: subchart diff --git a/cmd/helm/testdata/output/template-with-api-version.txt b/cmd/helm/testdata/output/template-with-api-version.txt index 210dcc503..ea4b5c96b 100644 --- a/cmd/helm/testdata/output/template-with-api-version.txt +++ b/cmd/helm/testdata/output/template-with-api-version.txt @@ -1,34 +1,34 @@ --- -# Source: subchart1/templates/subdir/serviceaccount.yaml +# Source: subchart/templates/subdir/serviceaccount.yaml apiVersion: v1 kind: ServiceAccount metadata: - name: subchart1-sa + name: subchart-sa --- -# Source: subchart1/templates/subdir/role.yaml +# Source: subchart/templates/subdir/role.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: - name: subchart1-role + name: subchart-role rules: - resources: ["*"] verbs: ["get","list","watch"] --- -# Source: subchart1/templates/subdir/rolebinding.yaml +# Source: subchart/templates/subdir/rolebinding.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: - name: subchart1-binding + name: subchart-binding roleRef: apiGroup: rbac.authorization.k8s.io kind: Role - name: subchart1-role + name: subchart-role subjects: - kind: ServiceAccount - name: subchart1-sa + name: subchart-sa namespace: default --- -# Source: subchart1/charts/subcharta/templates/service.yaml +# Source: subchart/charts/subcharta/templates/service.yaml apiVersion: v1 kind: Service metadata: @@ -45,7 +45,7 @@ spec: selector: app.kubernetes.io/name: subcharta --- -# Source: subchart1/charts/subchartb/templates/service.yaml +# Source: subchart/charts/subchartb/templates/service.yaml apiVersion: v1 kind: Service metadata: @@ -62,13 +62,13 @@ spec: selector: app.kubernetes.io/name: subchartb --- -# Source: subchart1/templates/service.yaml +# Source: subchart/templates/service.yaml apiVersion: v1 kind: Service metadata: - name: subchart1 + name: subchart labels: - helm.sh/chart: "subchart1-0.1.0" + helm.sh/chart: "subchart-0.1.0" app.kubernetes.io/instance: "RELEASE-NAME" kube-version/major: "1" kube-version/minor: "18" @@ -82,4 +82,4 @@ spec: protocol: TCP name: nginx selector: - app.kubernetes.io/name: subchart1 + app.kubernetes.io/name: subchart diff --git a/cmd/helm/testdata/output/template-with-crds.txt b/cmd/helm/testdata/output/template-with-crds.txt index 289eec291..fa2a79bac 100644 --- a/cmd/helm/testdata/output/template-with-crds.txt +++ b/cmd/helm/testdata/output/template-with-crds.txt @@ -15,36 +15,36 @@ spec: singular: authconfig --- -# Source: subchart1/templates/subdir/serviceaccount.yaml +# Source: subchart/templates/subdir/serviceaccount.yaml apiVersion: v1 kind: ServiceAccount metadata: - name: subchart1-sa + name: subchart-sa --- -# Source: subchart1/templates/subdir/role.yaml +# Source: subchart/templates/subdir/role.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: - name: subchart1-role + name: subchart-role rules: - resources: ["*"] verbs: ["get","list","watch"] --- -# Source: subchart1/templates/subdir/rolebinding.yaml +# Source: subchart/templates/subdir/rolebinding.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: - name: subchart1-binding + name: subchart-binding roleRef: apiGroup: rbac.authorization.k8s.io kind: Role - name: subchart1-role + name: subchart-role subjects: - kind: ServiceAccount - name: subchart1-sa + name: subchart-sa namespace: default --- -# Source: subchart1/charts/subcharta/templates/service.yaml +# Source: subchart/charts/subcharta/templates/service.yaml apiVersion: v1 kind: Service metadata: @@ -61,7 +61,7 @@ spec: selector: app.kubernetes.io/name: subcharta --- -# Source: subchart1/charts/subchartb/templates/service.yaml +# Source: subchart/charts/subchartb/templates/service.yaml apiVersion: v1 kind: Service metadata: @@ -78,13 +78,13 @@ spec: selector: app.kubernetes.io/name: subchartb --- -# Source: subchart1/templates/service.yaml +# Source: subchart/templates/service.yaml apiVersion: v1 kind: Service metadata: - name: subchart1 + name: subchart labels: - helm.sh/chart: "subchart1-0.1.0" + helm.sh/chart: "subchart-0.1.0" app.kubernetes.io/instance: "RELEASE-NAME" kube-version/major: "1" kube-version/minor: "18" @@ -98,4 +98,4 @@ spec: protocol: TCP name: nginx selector: - app.kubernetes.io/name: subchart1 + app.kubernetes.io/name: subchart diff --git a/cmd/helm/testdata/output/template.txt b/cmd/helm/testdata/output/template.txt index 82a21c5a1..9195f98b7 100644 --- a/cmd/helm/testdata/output/template.txt +++ b/cmd/helm/testdata/output/template.txt @@ -1,34 +1,34 @@ --- -# Source: subchart1/templates/subdir/serviceaccount.yaml +# Source: subchart/templates/subdir/serviceaccount.yaml apiVersion: v1 kind: ServiceAccount metadata: - name: subchart1-sa + name: subchart-sa --- -# Source: subchart1/templates/subdir/role.yaml +# Source: subchart/templates/subdir/role.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: - name: subchart1-role + name: subchart-role rules: - resources: ["*"] verbs: ["get","list","watch"] --- -# Source: subchart1/templates/subdir/rolebinding.yaml +# Source: subchart/templates/subdir/rolebinding.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: - name: subchart1-binding + name: subchart-binding roleRef: apiGroup: rbac.authorization.k8s.io kind: Role - name: subchart1-role + name: subchart-role subjects: - kind: ServiceAccount - name: subchart1-sa + name: subchart-sa namespace: default --- -# Source: subchart1/charts/subcharta/templates/service.yaml +# Source: subchart/charts/subcharta/templates/service.yaml apiVersion: v1 kind: Service metadata: @@ -45,7 +45,7 @@ spec: selector: app.kubernetes.io/name: subcharta --- -# Source: subchart1/charts/subchartb/templates/service.yaml +# Source: subchart/charts/subchartb/templates/service.yaml apiVersion: v1 kind: Service metadata: @@ -62,13 +62,13 @@ spec: selector: app.kubernetes.io/name: subchartb --- -# Source: subchart1/templates/service.yaml +# Source: subchart/templates/service.yaml apiVersion: v1 kind: Service metadata: - name: subchart1 + name: subchart labels: - helm.sh/chart: "subchart1-0.1.0" + helm.sh/chart: "subchart-0.1.0" app.kubernetes.io/instance: "RELEASE-NAME" kube-version/major: "1" kube-version/minor: "18" @@ -81,4 +81,4 @@ spec: protocol: TCP name: nginx selector: - app.kubernetes.io/name: subchart1 + app.kubernetes.io/name: subchart diff --git a/cmd/helm/testdata/testcharts/chart-with-no-templates-dir/values.yaml b/cmd/helm/testdata/testcharts/chart-with-no-templates-dir/values.yaml deleted file mode 100644 index ec82367be..000000000 --- a/cmd/helm/testdata/testcharts/chart-with-no-templates-dir/values.yaml +++ /dev/null @@ -1 +0,0 @@ -justAValue: "an example chart here" diff --git a/cmd/helm/testdata/testcharts/decompressedchart/.helmignore b/cmd/helm/testdata/testcharts/decompressedchart/.helmignore deleted file mode 100644 index 435b756d8..000000000 --- a/cmd/helm/testdata/testcharts/decompressedchart/.helmignore +++ /dev/null @@ -1,5 +0,0 @@ -# Patterns to ignore when building packages. -# This supports shell glob matching, relative path matching, and -# negation (prefixed with !). Only one pattern per line. -.DS_Store -.git diff --git a/cmd/helm/testdata/testcharts/novals/Chart.yaml b/cmd/helm/testdata/testcharts/novals/Chart.yaml deleted file mode 100644 index a4282470b..000000000 --- a/cmd/helm/testdata/testcharts/novals/Chart.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: v1 -description: Deploy a basic Alpine Linux pod -home: https://helm.sh/helm -name: novals -sources: - - https://github.com/helm/helm -version: 0.2.0 -appVersion: 3.3 diff --git a/cmd/helm/testdata/testcharts/novals/README.md b/cmd/helm/testdata/testcharts/novals/README.md deleted file mode 100644 index fcf7ee017..000000000 --- a/cmd/helm/testdata/testcharts/novals/README.md +++ /dev/null @@ -1,13 +0,0 @@ -#Alpine: A simple Helm chart - -Run a single pod of Alpine Linux. - -This example was generated using the command `helm create alpine`. - -The `templates/` directory contains a very simple pod resource with a -couple of parameters. - -The `values.yaml` file contains the default values for the -`alpine-pod.yaml` template. - -You can install this example using `helm install ./alpine`. diff --git a/cmd/helm/testdata/testcharts/novals/templates/alpine-pod.yaml b/cmd/helm/testdata/testcharts/novals/templates/alpine-pod.yaml deleted file mode 100644 index 96c92d61d..000000000 --- a/cmd/helm/testdata/testcharts/novals/templates/alpine-pod.yaml +++ /dev/null @@ -1,28 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - name: "{{.Release.Name}}-{{.Values.Name}}" - labels: - # The "app.kubernetes.io/managed-by" label is used to track which tool - # deployed a given chart. It is useful for admins who want to see what - # releases a particular tool is responsible for. - app.kubernetes.io/managed-by: {{.Release.Service | quote }} - # The "app.kubernetes.io/instance" convention makes it easy to tie a release - # to all of the Kubernetes resources that were created as part of that - # release. - app.kubernetes.io/instance: {{.Release.Name | quote }} - app.kubernetes.io/version: {{ .Chart.AppVersion }} - # This makes it easy to audit chart usage. - helm.sh/chart: "{{.Chart.Name}}-{{.Chart.Version}}" - annotations: - "helm.sh/created": {{.Release.Time.Seconds | quote }} -spec: - # This shows how to use a simple value. This will look for a passed-in value - # called restartPolicy. If it is not found, it will use the default value. - # {{default "Never" .restartPolicy}} is a slightly optimized version of the - # more conventional syntax: {{.restartPolicy | default "Never"}} - restartPolicy: {{default "Never" .Values.restartPolicy}} - containers: - - name: waiter - image: "alpine:3.3" - command: ["/bin/sleep","9000"] diff --git a/cmd/helm/testdata/testcharts/subchart/Chart.yaml b/cmd/helm/testdata/testcharts/subchart/Chart.yaml new file mode 100644 index 000000000..b03ea3cd3 --- /dev/null +++ b/cmd/helm/testdata/testcharts/subchart/Chart.yaml @@ -0,0 +1,36 @@ +apiVersion: v1 +description: A Helm chart for Kubernetes +name: subchart +version: 0.1.0 +dependencies: + - name: subcharta + repository: http://localhost:10191 + version: 0.1.0 + condition: subcharta.enabled + tags: + - front-end + - subcharta + import-values: + - child: SCAdata + parent: imported-chartA + - child: SCAdata + parent: overridden-chartA + - child: SCAdata + parent: imported-chartA-B + + - name: subchartb + repository: http://localhost:10191 + version: 0.1.0 + condition: subchartb.enabled + import-values: + - child: SCBdata + parent: imported-chartB + - child: SCBdata + parent: imported-chartA-B + - child: exports.SCBexported2 + parent: exports.SCBexported2 + - SCBexported1 + + tags: + - front-end + - subchartb diff --git a/cmd/helm/testdata/testcharts/subchart/charts/subchartA/Chart.yaml b/cmd/helm/testdata/testcharts/subchart/charts/subchartA/Chart.yaml new file mode 100644 index 000000000..be3edcefb --- /dev/null +++ b/cmd/helm/testdata/testcharts/subchart/charts/subchartA/Chart.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +description: A Helm chart for Kubernetes +name: subcharta +version: 0.1.0 diff --git a/cmd/helm/testdata/testcharts/subchart/charts/subchartA/templates/service.yaml b/cmd/helm/testdata/testcharts/subchart/charts/subchartA/templates/service.yaml new file mode 100644 index 000000000..27501e1e0 --- /dev/null +++ b/cmd/helm/testdata/testcharts/subchart/charts/subchartA/templates/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ .Chart.Name }} + labels: + helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.externalPort }} + targetPort: {{ .Values.service.internalPort }} + protocol: TCP + name: {{ .Values.service.name }} + selector: + app.kubernetes.io/name: {{ .Chart.Name }} diff --git a/cmd/helm/testdata/testcharts/subchart/charts/subchartA/values.yaml b/cmd/helm/testdata/testcharts/subchart/charts/subchartA/values.yaml new file mode 100644 index 000000000..f0381ae6a --- /dev/null +++ b/cmd/helm/testdata/testcharts/subchart/charts/subchartA/values.yaml @@ -0,0 +1,17 @@ +# Default values for subchart. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. +# subchartA +service: + name: apache + type: ClusterIP + externalPort: 80 + internalPort: 80 +SCAdata: + SCAbool: false + SCAfloat: 3.1 + SCAint: 55 + SCAstring: "jabba" + SCAnested1: + SCAnested2: true + diff --git a/cmd/helm/testdata/testcharts/subchart/charts/subchartB/Chart.yaml b/cmd/helm/testdata/testcharts/subchart/charts/subchartB/Chart.yaml new file mode 100644 index 000000000..c3c6bbaf0 --- /dev/null +++ b/cmd/helm/testdata/testcharts/subchart/charts/subchartB/Chart.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +description: A Helm chart for Kubernetes +name: subchartb +version: 0.1.0 diff --git a/cmd/helm/testdata/testcharts/subchart/charts/subchartB/templates/service.yaml b/cmd/helm/testdata/testcharts/subchart/charts/subchartB/templates/service.yaml new file mode 100644 index 000000000..27501e1e0 --- /dev/null +++ b/cmd/helm/testdata/testcharts/subchart/charts/subchartB/templates/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ .Chart.Name }} + labels: + helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.externalPort }} + targetPort: {{ .Values.service.internalPort }} + protocol: TCP + name: {{ .Values.service.name }} + selector: + app.kubernetes.io/name: {{ .Chart.Name }} diff --git a/cmd/helm/testdata/testcharts/subchart/charts/subchartB/values.yaml b/cmd/helm/testdata/testcharts/subchart/charts/subchartB/values.yaml new file mode 100644 index 000000000..774fdd75c --- /dev/null +++ b/cmd/helm/testdata/testcharts/subchart/charts/subchartB/values.yaml @@ -0,0 +1,35 @@ +# Default values for subchart. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. +service: + name: nginx + type: ClusterIP + externalPort: 80 + internalPort: 80 + +SCBdata: + SCBbool: true + SCBfloat: 7.77 + SCBint: 33 + SCBstring: "boba" + +exports: + SCBexported1: + SCBexported1A: + SCBexported1B: 1965 + + SCBexported2: + SCBexported2A: "blaster" + +global: + kolla: + nova: + api: + all: + port: 8774 + metadata: + all: + port: 8775 + + + diff --git a/cmd/helm/testdata/testcharts/subchart/crds/crdA.yaml b/cmd/helm/testdata/testcharts/subchart/crds/crdA.yaml new file mode 100644 index 000000000..fca77fd4b --- /dev/null +++ b/cmd/helm/testdata/testcharts/subchart/crds/crdA.yaml @@ -0,0 +1,13 @@ +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: testCRDs +spec: + group: testCRDGroups + names: + kind: TestCRD + listKind: TestCRDList + plural: TestCRDs + shortNames: + - tc + singular: authconfig diff --git a/cmd/helm/testdata/testcharts/subchart/templates/NOTES.txt b/cmd/helm/testdata/testcharts/subchart/templates/NOTES.txt new file mode 100644 index 000000000..4bdf443f6 --- /dev/null +++ b/cmd/helm/testdata/testcharts/subchart/templates/NOTES.txt @@ -0,0 +1 @@ +Sample notes for {{ .Chart.Name }} \ No newline at end of file diff --git a/cmd/helm/testdata/testcharts/subchart/templates/service.yaml b/cmd/helm/testdata/testcharts/subchart/templates/service.yaml new file mode 100644 index 000000000..fee94dced --- /dev/null +++ b/cmd/helm/testdata/testcharts/subchart/templates/service.yaml @@ -0,0 +1,22 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ .Chart.Name }} + labels: + helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + app.kubernetes.io/instance: "{{ .Release.Name }}" + kube-version/major: "{{ .Capabilities.KubeVersion.Major }}" + kube-version/minor: "{{ .Capabilities.KubeVersion.Minor }}" + kube-version/version: "v{{ .Capabilities.KubeVersion.Major }}.{{ .Capabilities.KubeVersion.Minor }}.0" +{{- if .Capabilities.APIVersions.Has "helm.k8s.io/test" }} + kube-api-version/test: v1 +{{- end }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.externalPort }} + targetPort: {{ .Values.service.internalPort }} + protocol: TCP + name: {{ .Values.service.name }} + selector: + app.kubernetes.io/name: {{ .Chart.Name }} diff --git a/cmd/helm/testdata/testcharts/subchart/templates/subdir/role.yaml b/cmd/helm/testdata/testcharts/subchart/templates/subdir/role.yaml new file mode 100644 index 000000000..91b954e5f --- /dev/null +++ b/cmd/helm/testdata/testcharts/subchart/templates/subdir/role.yaml @@ -0,0 +1,7 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ .Chart.Name }}-role +rules: +- resources: ["*"] + verbs: ["get","list","watch"] diff --git a/cmd/helm/testdata/testcharts/subchart/templates/subdir/rolebinding.yaml b/cmd/helm/testdata/testcharts/subchart/templates/subdir/rolebinding.yaml new file mode 100644 index 000000000..5d193f1a6 --- /dev/null +++ b/cmd/helm/testdata/testcharts/subchart/templates/subdir/rolebinding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ .Chart.Name }}-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ .Chart.Name }}-role +subjects: +- kind: ServiceAccount + name: {{ .Chart.Name }}-sa + namespace: default diff --git a/cmd/helm/testdata/testcharts/subchart/templates/subdir/serviceaccount.yaml b/cmd/helm/testdata/testcharts/subchart/templates/subdir/serviceaccount.yaml new file mode 100644 index 000000000..7126c7d89 --- /dev/null +++ b/cmd/helm/testdata/testcharts/subchart/templates/subdir/serviceaccount.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Chart.Name }}-sa diff --git a/cmd/helm/testdata/testcharts/subchart/values.yaml b/cmd/helm/testdata/testcharts/subchart/values.yaml new file mode 100644 index 000000000..8a3ab6c64 --- /dev/null +++ b/cmd/helm/testdata/testcharts/subchart/values.yaml @@ -0,0 +1,55 @@ +# Default values for subchart. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. +# subchart +service: + name: nginx + type: ClusterIP + externalPort: 80 + internalPort: 80 + + +SC1data: + SC1bool: true + SC1float: 3.14 + SC1int: 100 + SC1string: "dollywood" + SC1extra1: 11 + +imported-chartA: + SC1extra2: 1.337 + +overridden-chartA: + SCAbool: true + SCAfloat: 3.14 + SCAint: 100 + SCAstring: "jabbathehut" + SC1extra3: true + +imported-chartA-B: + SC1extra5: "tiller" + +overridden-chartA-B: + SCAbool: true + SCAfloat: 3.33 + SCAint: 555 + SCAstring: "wormwood" + SCAextra1: 23 + + SCBbool: true + SCBfloat: 0.25 + SCBint: 98 + SCBstring: "murkwood" + SCBextra1: 13 + + SC1extra6: 77 + +SCBexported1A: + SC1extra7: true + +exports: + SC1exported1: + global: + SC1exported2: + all: + SC1exported3: "SC1expstr" diff --git a/internal/resolver/resolver_test.go b/internal/resolver/resolver_test.go index bb3d3e6ac..0b0c3a6f8 100644 --- a/internal/resolver/resolver_test.go +++ b/internal/resolver/resolver_test.go @@ -74,18 +74,18 @@ func TestResolve(t *testing.T) { { name: "repo from valid local path", req: []*chart.Dependency{ - {Name: "signtest", Repository: "file://../../../../cmd/helm/testdata/testcharts/signtest", Version: "0.1.0"}, + {Name: "base", Repository: "file://base", Version: "0.1.0"}, }, expect: &chart.Lock{ Dependencies: []*chart.Dependency{ - {Name: "signtest", Repository: "file://../../../../cmd/helm/testdata/testcharts/signtest", Version: "0.1.0"}, + {Name: "base", Repository: "file://base", Version: "0.1.0"}, }, }, }, { name: "repo from invalid local path", req: []*chart.Dependency{ - {Name: "notexist", Repository: "file://../testdata/notexist", Version: "0.1.0"}, + {Name: "notexist", Repository: "file://testdata/notexist", Version: "0.1.0"}, }, err: true, }, @@ -232,9 +232,9 @@ func TestGetLocalPath(t *testing.T) { }, { name: "relative path", - repo: "file://../../../../cmd/helm/testdata/testcharts/signtest", + repo: "file://../../testdata/chartpath/base", chartpath: "foo/bar", - expect: "../../cmd/helm/testdata/testcharts/signtest", + expect: "testdata/chartpath/base", }, { name: "current directory path", @@ -244,13 +244,13 @@ func TestGetLocalPath(t *testing.T) { }, { name: "invalid local path", - repo: "file://../testdata/notexist", + repo: "file://testdata/notexist", chartpath: "testdata/chartpath", err: true, }, { name: "invalid path under current directory", - repo: "../charts/nonexistentdependency", + repo: "charts/nonexistentdependency", chartpath: "testdata/chartpath/charts", err: true, }, diff --git a/internal/resolver/testdata/chartpath/base/Chart.yaml b/internal/resolver/testdata/chartpath/base/Chart.yaml new file mode 100644 index 000000000..860b09091 --- /dev/null +++ b/internal/resolver/testdata/chartpath/base/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: base +version: 0.1.0 diff --git a/pkg/action/dependency_test.go b/pkg/action/dependency_test.go index 158acbfb9..4f3cb69a5 100644 --- a/pkg/action/dependency_test.go +++ b/pkg/action/dependency_test.go @@ -30,23 +30,23 @@ func TestList(t *testing.T) { }{ { chart: "testdata/charts/chart-with-compressed-dependencies", - golden: "output/compressed-deps.txt", + golden: "output/list-compressed-deps.txt", }, { chart: "testdata/charts/chart-with-compressed-dependencies-2.1.8.tgz", - golden: "output/compressed-deps-tgz.txt", + golden: "output/list-compressed-deps-tgz.txt", }, { chart: "testdata/charts/chart-with-uncompressed-dependencies", - golden: "output/uncompressed-deps.txt", + golden: "output/list-uncompressed-deps.txt", }, { chart: "testdata/charts/chart-with-uncompressed-dependencies-2.1.8.tgz", - golden: "output/uncompressed-deps-tgz.txt", + golden: "output/list-uncompressed-deps-tgz.txt", }, { chart: "testdata/charts/chart-missing-deps", - golden: "output/missing-deps.txt", + golden: "output/list-missing-deps.txt", }, } { buf := bytes.Buffer{} diff --git a/pkg/action/lint_test.go b/pkg/action/lint_test.go index 68d3c4bb4..1828461f3 100644 --- a/pkg/action/lint_test.go +++ b/pkg/action/lint_test.go @@ -24,10 +24,10 @@ var ( values = make(map[string]interface{}) namespace = "testNamespace" strict = false - chart1MultipleChartLint = "../../cmd/helm/testdata/testcharts/multiplecharts-lint-chart-1" - chart2MultipleChartLint = "../../cmd/helm/testdata/testcharts/multiplecharts-lint-chart-2" - corruptedTgzChart = "../../cmd/helm/testdata/testcharts/corrupted-compressed-chart.tgz" - chartWithNoTemplatesDir = "../../cmd/helm/testdata/testcharts/chart-with-no-templates-dir" + chart1MultipleChartLint = "testdata/charts/multiplecharts-lint-chart-1" + chart2MultipleChartLint = "testdata/charts/multiplecharts-lint-chart-2" + corruptedTgzChart = "testdata/charts/corrupted-compressed-chart.tgz" + chartWithNoTemplatesDir = "testdata/charts/chart-with-no-templates-dir" ) func TestLintChart(t *testing.T) { @@ -38,41 +38,41 @@ func TestLintChart(t *testing.T) { }{ { name: "decompressed-chart", - chartPath: "../../cmd/helm/testdata/testcharts/decompressedchart/", + chartPath: "testdata/charts/decompressedchart/", }, { name: "archived-chart-path", - chartPath: "../../cmd/helm/testdata/testcharts/compressedchart-0.1.0.tgz", + chartPath: "testdata/charts/compressedchart-0.1.0.tgz", }, { name: "archived-chart-path-with-hyphens", - chartPath: "../../cmd/helm/testdata/testcharts/compressedchart-with-hyphens-0.1.0.tgz", + chartPath: "testdata/charts/compressedchart-with-hyphens-0.1.0.tgz", }, { name: "archived-tar-gz-chart-path", - chartPath: "../../cmd/helm/testdata/testcharts/compressedchart-0.1.0.tar.gz", + chartPath: "testdata/charts/compressedchart-0.1.0.tar.gz", }, { name: "invalid-archived-chart-path", - chartPath: "../../cmd/helm/testdata/testcharts/invalidcompressedchart0.1.0.tgz", + chartPath: "testdata/charts/invalidcompressedchart0.1.0.tgz", err: true, }, { name: "chart-missing-manifest", - chartPath: "../../cmd/helm/testdata/testcharts/chart-missing-manifest", + chartPath: "testdata/charts/chart-missing-manifest", err: true, }, { name: "chart-with-schema", - chartPath: "../../cmd/helm/testdata/testcharts/chart-with-schema", + chartPath: "testdata/charts/chart-with-schema", }, { name: "chart-with-schema-negative", - chartPath: "../../cmd/helm/testdata/testcharts/chart-with-schema-negative", + chartPath: "testdata/charts/chart-with-schema-negative", }, { name: "pre-release-chart", - chartPath: "../../cmd/helm/testdata/testcharts/pre-release-chart-0.1.0-alpha.tgz", + chartPath: "testdata/charts/pre-release-chart-0.1.0-alpha.tgz", }, } diff --git a/pkg/action/show.go b/pkg/action/show.go index cc85477cd..9baa9cf43 100644 --- a/pkg/action/show.go +++ b/pkg/action/show.go @@ -54,6 +54,7 @@ type Show struct { ChartPathOptions Devel bool OutputFormat ShowOutputFormat + chart *chart.Chart // for testing } // NewShow creates a new Show object with the given configuration. @@ -65,25 +66,28 @@ func NewShow(output ShowOutputFormat) *Show { // Run executes 'helm show' against the given release. func (s *Show) Run(chartpath string) (string, error) { - var out strings.Builder - chrt, err := loader.Load(chartpath) - if err != nil { - return "", err + if s.chart == nil { + chrt, err := loader.Load(chartpath) + if err != nil { + return "", err + } + s.chart = chrt } - cf, err := yaml.Marshal(chrt.Metadata) + cf, err := yaml.Marshal(s.chart.Metadata) if err != nil { return "", err } + var out strings.Builder if s.OutputFormat == ShowChart || s.OutputFormat == ShowAll { fmt.Fprintf(&out, "%s\n", cf) } - if (s.OutputFormat == ShowValues || s.OutputFormat == ShowAll) && chrt.Values != nil { + if (s.OutputFormat == ShowValues || s.OutputFormat == ShowAll) && s.chart.Values != nil { if s.OutputFormat == ShowAll { fmt.Fprintln(&out, "---") } - for _, f := range chrt.Raw { + for _, f := range s.chart.Raw { if f.Name == chartutil.ValuesfileName { fmt.Fprintln(&out, string(f.Data)) } @@ -94,7 +98,7 @@ func (s *Show) Run(chartpath string) (string, error) { if s.OutputFormat == ShowAll { fmt.Fprintln(&out, "---") } - readme := findReadme(chrt.Files) + readme := findReadme(s.chart.Files) if readme == nil { return out.String(), nil } diff --git a/pkg/action/show_test.go b/pkg/action/show_test.go index 0a532746a..7be9daaa5 100644 --- a/pkg/action/show_test.go +++ b/pkg/action/show_test.go @@ -17,55 +17,50 @@ limitations under the License. package action import ( - "io/ioutil" - "strings" "testing" + + "helm.sh/helm/v3/pkg/chart" ) func TestShow(t *testing.T) { client := NewShow(ShowAll) - - output, err := client.Run("../../cmd/helm/testdata/testcharts/alpine") - if err != nil { - t.Fatal(err) + client.chart = &chart.Chart{ + Metadata: &chart.Metadata{Name: "alpine"}, + Files: []*chart.File{ + {Name: "README.md", Data: []byte("README\n")}, + }, + Raw: []*chart.File{ + {Name: "values.yaml", Data: []byte("VALUES\n")}, + }, + Values: map[string]interface{}{}, } - // Load the data from the textfixture directly. - cdata, err := ioutil.ReadFile("../../cmd/helm/testdata/testcharts/alpine/Chart.yaml") + output, err := client.Run("") if err != nil { t.Fatal(err) } - data, err := ioutil.ReadFile("../../cmd/helm/testdata/testcharts/alpine/values.yaml") - if err != nil { - t.Fatal(err) - } - readmeData, err := ioutil.ReadFile("../../cmd/helm/testdata/testcharts/alpine/README.md") - if err != nil { - t.Fatal(err) - } - parts := strings.SplitN(output, "---", 3) - if len(parts) != 3 { - t.Fatalf("Expected 2 parts, got %d", len(parts)) - } - expect := []string{ - strings.ReplaceAll(strings.TrimSpace(string(cdata)), "\r", ""), - strings.ReplaceAll(strings.TrimSpace(string(data)), "\r", ""), - strings.ReplaceAll(strings.TrimSpace(string(readmeData)), "\r", ""), - } + expect := `name: alpine + +--- +VALUES - // Problem: ghodss/yaml doesn't marshal into struct order. To solve, we - // have to carefully craft the Chart.yaml to match. - for i, got := range parts { - got = strings.ReplaceAll(strings.TrimSpace(got), "\r", "") - if got != expect[i] { - t.Errorf("Expected\n%q\nGot\n%q\n", expect[i], got) - } +--- +README + +` + if output != expect { + t.Errorf("Expected\n%q\nGot\n%q\n", expect, output) } +} + +func TestShowNoValues(t *testing.T) { + client := NewShow(ShowAll) + client.chart = new(chart.Chart) // Regression tests for missing values. See issue #1024. client.OutputFormat = ShowValues - output, err = client.Run("../../cmd/helm/testdata/testcharts/novals") + output, err := client.Run("") if err != nil { t.Fatal(err) } diff --git a/pkg/action/testdata/charts/chart-missing-deps/.helmignore b/pkg/action/testdata/charts/chart-missing-deps/.helmignore deleted file mode 100755 index e2cf7941f..000000000 --- a/pkg/action/testdata/charts/chart-missing-deps/.helmignore +++ /dev/null @@ -1,5 +0,0 @@ -.git -# OWNERS file for Kubernetes -OWNERS -# example production yaml -values-production.yaml \ No newline at end of file diff --git a/pkg/action/testdata/charts/chart-missing-deps/Chart.yaml b/pkg/action/testdata/charts/chart-missing-deps/Chart.yaml index 8304984fd..ba10ee803 100755 --- a/pkg/action/testdata/charts/chart-missing-deps/Chart.yaml +++ b/pkg/action/testdata/charts/chart-missing-deps/Chart.yaml @@ -1,20 +1,2 @@ -appVersion: 4.9.8 -description: Web publishing platform for building blogs and websites. -engine: gotpl -home: http://www.wordpress.com/ -icon: https://bitnami.com/assets/stacks/wordpress/img/wordpress-stack-220x234.png -keywords: -- wordpress -- cms -- blog -- http -- web -- application -- php -maintainers: -- email: containers@bitnami.com - name: bitnami-bot name: chart-with-missing-deps -sources: -- https://github.com/bitnami/bitnami-docker-wordpress version: 2.1.8 diff --git a/pkg/action/testdata/charts/chart-missing-deps/README.md b/pkg/action/testdata/charts/chart-missing-deps/README.md deleted file mode 100755 index 5859a17fa..000000000 --- a/pkg/action/testdata/charts/chart-missing-deps/README.md +++ /dev/null @@ -1,232 +0,0 @@ -# WordPress - -[WordPress](https://wordpress.org/) is one of the most versatile open source content management systems on the market. A publishing platform for building blogs and websites. - -## TL;DR; - -```console -$ helm install stable/wordpress -``` - -## Introduction - -This chart bootstraps a [WordPress](https://github.com/bitnami/bitnami-docker-wordpress) deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. - -It also packages the [Bitnami MariaDB chart](https://github.com/kubernetes/charts/tree/master/stable/mariadb) which is required for bootstrapping a MariaDB deployment for the database requirements of the WordPress application. - -## Prerequisites - -- Kubernetes 1.4+ with Beta APIs enabled -- PV provisioner support in the underlying infrastructure - -## Installing the Chart - -To install the chart with the release name `my-release`: - -```console -$ helm install --name my-release stable/wordpress -``` - -The command deploys WordPress on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation. - -> **Tip**: List all releases using `helm list` - -## Uninstalling the Chart - -To uninstall/delete the `my-release` deployment: - -```console -$ helm delete my-release -``` - -The command removes all the Kubernetes components associated with the chart and deletes the release. - -## Configuration - -The following table lists the configurable parameters of the WordPress chart and their default values. - -| Parameter | Description | Default | -|----------------------------------|--------------------------------------------|---------------------------------------------------------| -| `image.registry` | WordPress image registry | `docker.io` | -| `image.repository` | WordPress image name | `bitnami/wordpress` | -| `image.tag` | WordPress image tag | `{VERSION}` | -| `image.pullPolicy` | Image pull policy | `Always` if `imageTag` is `latest`, else `IfNotPresent` | -| `image.pullSecrets` | Specify image pull secrets | `nil` | -| `wordpressUsername` | User of the application | `user` | -| `wordpressPassword` | Application password | _random 10 character long alphanumeric string_ | -| `wordpressEmail` | Admin email | `user@example.com` | -| `wordpressFirstName` | First name | `FirstName` | -| `wordpressLastName` | Last name | `LastName` | -| `wordpressBlogName` | Blog name | `User's Blog!` | -| `wordpressTablePrefix` | Table prefix | `wp_` | -| `allowEmptyPassword` | Allow DB blank passwords | `yes` | -| `smtpHost` | SMTP host | `nil` | -| `smtpPort` | SMTP port | `nil` | -| `smtpUser` | SMTP user | `nil` | -| `smtpPassword` | SMTP password | `nil` | -| `smtpUsername` | User name for SMTP emails | `nil` | -| `smtpProtocol` | SMTP protocol [`tls`, `ssl`] | `nil` | -| `replicaCount` | Number of WordPress Pods to run | `1` | -| `mariadb.enabled` | Deploy MariaDB container(s) | `true` | -| `mariadb.rootUser.password` | MariaDB admin password | `nil` | -| `mariadb.db.name` | Database name to create | `bitnami_wordpress` | -| `mariadb.db.user` | Database user to create | `bn_wordpress` | -| `mariadb.db.password` | Password for the database | _random 10 character long alphanumeric string_ | -| `externalDatabase.host` | Host of the external database | `localhost` | -| `externalDatabase.user` | Existing username in the external db | `bn_wordpress` | -| `externalDatabase.password` | Password for the above username | `nil` | -| `externalDatabase.database` | Name of the existing database | `bitnami_wordpress` | -| `externalDatabase.port` | Database port number | `3306` | -| `serviceType` | Kubernetes Service type | `LoadBalancer` | -| `serviceExternalTrafficPolicy` | Enable client source IP preservation | `Cluster` | -| `nodePorts.http` | Kubernetes http node port | `""` | -| `nodePorts.https` | Kubernetes https node port | `""` | -| `healthcheckHttps` | Use https for liveliness and readiness | `false` | -| `ingress.enabled` | Enable ingress controller resource | `false` | -| `ingress.hosts[0].name` | Hostname to your WordPress installation | `wordpress.local` | -| `ingress.hosts[0].path` | Path within the url structure | `/` | -| `ingress.hosts[0].tls` | Utilize TLS backend in ingress | `false` | -| `ingress.hosts[0].tlsSecret` | TLS Secret (certificates) | `wordpress.local-tls-secret` | -| `ingress.hosts[0].annotations` | Annotations for this host's ingress record | `[]` | -| `ingress.secrets[0].name` | TLS Secret Name | `nil` | -| `ingress.secrets[0].certificate` | TLS Secret Certificate | `nil` | -| `ingress.secrets[0].key` | TLS Secret Key | `nil` | -| `persistence.enabled` | Enable persistence using PVC | `true` | -| `persistence.existingClaim` | Enable persistence using an existing PVC | `nil` | -| `persistence.storageClass` | PVC Storage Class | `nil` (uses alpha storage class annotation) | -| `persistence.accessMode` | PVC Access Mode | `ReadWriteOnce` | -| `persistence.size` | PVC Storage Request | `10Gi` | -| `nodeSelector` | Node labels for pod assignment | `{}` | -| `tolerations` | List of node taints to tolerate | `[]` | -| `affinity` | Map of node/pod affinities | `{}` | - -The above parameters map to the env variables defined in [bitnami/wordpress](http://github.com/bitnami/bitnami-docker-wordpress). For more information please refer to the [bitnami/wordpress](http://github.com/bitnami/bitnami-docker-wordpress) image documentation. - -Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, - -```console -$ helm install --name my-release \ - --set wordpressUsername=admin,wordpressPassword=password,mariadb.mariadbRootPassword=secretpassword \ - stable/wordpress -``` - -The above command sets the WordPress administrator account username and password to `admin` and `password` respectively. Additionally, it sets the MariaDB `root` user password to `secretpassword`. - -Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the chart. For example, - -```console -$ helm install --name my-release -f values.yaml stable/wordpress -``` - -> **Tip**: You can use the default [values.yaml](values.yaml) - -## Production and horizontal scaling - -The following repo contains the recommended production settings for wordpress capture in an alternative [values file](values-production.yaml). Please read carefully the comments in the values-production.yaml file to set up your environment appropriately. - -To horizontally scale this chart, first download the [values-production.yaml](values-production.yaml) file to your local folder, then: - -```console -$ helm install --name my-release -f ./values-production.yaml stable/wordpress -``` - -Note that [values-production.yaml](values-production.yaml) includes a replicaCount of 3, so there will be 3 WordPress pods. As a result, to use the /admin portal and to ensure you can scale wordpress you need to provide a ReadWriteMany PVC, if you don't have a provisioner for this type of storage, we recommend that you install the nfs provisioner and map it to a RWO volume. - -```console -$ helm install stable/nfs-server-provisioner --set persistence.enabled=true,persistence.size=10Gi -$ helm install --name my-release -f values-production.yaml --set persistence.storageClass=nfs stable/wordpress -``` - -## Persistence - -The [Bitnami WordPress](https://github.com/bitnami/bitnami-docker-wordpress) image stores the WordPress data and configurations at the `/bitnami` path of the container. - -Persistent Volume Claims are used to keep the data across deployments. This is known to work in GCE, AWS, and minikube. -See the [Configuration](#configuration) section to configure the PVC or to disable persistence. - -## Using an external database - -Sometimes you may want to have Wordpress connect to an external database rather than installing one inside your cluster, e.g. to use a managed database service, or use run a single database server for all your applications. To do this, the chart allows you to specify credentials for an external database under the [`externalDatabase` parameter](#configuration). You should also disable the MariaDB installation with the `mariadb.enabled` option. For example: - -```console -$ helm install stable/wordpress \ - --set mariadb.enabled=false,externalDatabase.host=myexternalhost,externalDatabase.user=myuser,externalDatabase.password=mypassword,externalDatabase.database=mydatabase,externalDatabase.port=3306 -``` - -Note also if you disable MariaDB per above you MUST supply values for the `externalDatabase` connection. - -## Ingress - -This chart provides support for ingress resources. If you have an -ingress controller installed on your cluster, such as [nginx-ingress](https://kubeapps.com/charts/stable/nginx-ingress) -or [traefik](https://kubeapps.com/charts/stable/traefik) you can utilize -the ingress controller to serve your WordPress application. - -To enable ingress integration, please set `ingress.enabled` to `true` - -### Hosts - -Most likely you will only want to have one hostname that maps to this -WordPress installation, however, it is possible to have more than one -host. To facilitate this, the `ingress.hosts` object is an array. - -For each item, please indicate a `name`, `tls`, `tlsSecret`, and any -`annotations` that you may want the ingress controller to know about. - -Indicating TLS will cause WordPress to generate HTTPS URLs, and -WordPress will be connected to at port 443. The actual secret that -`tlsSecret` references do not have to be generated by this chart. -However, please note that if TLS is enabled, the ingress record will not -work until this secret exists. - -For annotations, please see [this document](https://github.com/kubernetes/ingress-nginx/blob/master/docs/annotations.md). -Not all annotations are supported by all ingress controllers, but this -document does a good job of indicating which annotation is supported by -many popular ingress controllers. - -### TLS Secrets - -This chart will facilitate the creation of TLS secrets for use with the -ingress controller, however, this is not required. There are three -common use cases: - -* helm generates/manages certificate secrets -* user generates/manages certificates separately -* an additional tool (like [kube-lego](https://kubeapps.com/charts/stable/kube-lego)) -manages the secrets for the application - -In the first two cases, one will need a certificate and a key. We would -expect them to look like this: - -* certificate files should look like (and there can be more than one -certificate if there is a certificate chain) - -``` ------BEGIN CERTIFICATE----- -MIID6TCCAtGgAwIBAgIJAIaCwivkeB5EMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV -... -jScrvkiBO65F46KioCL9h5tDvomdU1aqpI/CBzhvZn1c0ZTf87tGQR8NK7v7 ------END CERTIFICATE----- -``` -* keys should look like: -``` ------BEGIN RSA PRIVATE KEY----- -MIIEogIBAAKCAQEAvLYcyu8f3skuRyUgeeNpeDvYBCDcgq+LsWap6zbX5f8oLqp4 -... -wrj2wDbCDCFmfqnSJ+dKI3vFLlEz44sAV8jX/kd4Y6ZTQhlLbYc= ------END RSA PRIVATE KEY----- -```` - -If you are going to use Helm to manage the certificates, please copy -these values into the `certificate` and `key` values for a given -`ingress.secrets` entry. - -If you are going are going to manage TLS secrets outside of Helm, please -know that you can create a TLS secret by doing the following: - -``` -kubectl create secret tls wordpress.local-tls --key /path/to/key.key --cert /path/to/cert.crt -``` - -Please see [this example](https://github.com/kubernetes/contrib/tree/master/ingress/controllers/nginx/examples/tls) -for more information. diff --git a/pkg/action/testdata/charts/chart-missing-deps/templates/NOTES.txt b/pkg/action/testdata/charts/chart-missing-deps/templates/NOTES.txt deleted file mode 100755 index 55626e4d1..000000000 --- a/pkg/action/testdata/charts/chart-missing-deps/templates/NOTES.txt +++ /dev/null @@ -1,38 +0,0 @@ -1. Get the WordPress URL: - -{{- if .Values.ingress.enabled }} - - You should be able to access your new WordPress installation through - - {{- range .Values.ingress.hosts }} - {{ if .tls }}https{{ else }}http{{ end }}://{{ .name }}/admin - {{- end }} - -{{- else if contains "LoadBalancer" .Values.serviceType }} - - NOTE: It may take a few minutes for the LoadBalancer IP to be available. - Watch the status with: 'kubectl get svc --namespace {{ .Release.Namespace }} -w {{ template "fullname" . }}' - - export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') - echo "WordPress URL: http://$SERVICE_IP/" - echo "WordPress Admin URL: http://$SERVICE_IP/admin" - -{{- else if contains "ClusterIP" .Values.serviceType }} - - echo "WordPress URL: http://127.0.0.1:8080/" - echo "WordPress Admin URL: http://127.0.0.1:8080/admin" - kubectl port-forward --namespace {{ .Release.Namespace }} svc/{{ template "fullname" . }} 8080:80 - -{{- else if contains "NodePort" .Values.serviceType }} - - export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "fullname" . }}) - export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") - echo "WordPress URL: http://$NODE_IP:$NODE_PORT/" - echo "WordPress Admin URL: http://$NODE_IP:$NODE_PORT/admin" - -{{- end }} - -2. Login with the following credentials to see your blog - - echo Username: {{ .Values.wordpressUsername }} - echo Password: $(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "fullname" . }} -o jsonpath="{.data.wordpress-password}" | base64 --decode) diff --git a/pkg/action/testdata/charts/chart-missing-deps/templates/_helpers.tpl b/pkg/action/testdata/charts/chart-missing-deps/templates/_helpers.tpl deleted file mode 100755 index 1e52d321c..000000000 --- a/pkg/action/testdata/charts/chart-missing-deps/templates/_helpers.tpl +++ /dev/null @@ -1,24 +0,0 @@ -{{/* vim: set filetype=mustache: */}} -{{/* -Expand the name of the chart. -*/}} -{{- define "name" -}} -{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Create a default fully qualified app name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -*/}} -{{- define "fullname" -}} -{{- $name := default .Chart.Name .Values.nameOverride -}} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Create a default fully qualified app name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -*/}} -{{- define "mariadb.fullname" -}} -{{- printf "%s-%s" .Release.Name "mariadb" | trunc 63 | trimSuffix "-" -}} -{{- end -}} diff --git a/pkg/action/testdata/charts/chart-missing-deps/values.yaml b/pkg/action/testdata/charts/chart-missing-deps/values.yaml deleted file mode 100755 index 3cb66dafd..000000000 --- a/pkg/action/testdata/charts/chart-missing-deps/values.yaml +++ /dev/null @@ -1,254 +0,0 @@ -## Bitnami WordPress image version -## ref: https://hub.docker.com/r/bitnami/wordpress/tags/ -## -image: - registry: docker.io - repository: bitnami/wordpress - tag: 4.9.8-debian-9 - ## Specify a imagePullPolicy - ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' - ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images - ## - pullPolicy: IfNotPresent - ## Optionally specify an array of imagePullSecrets. - ## Secrets must be manually created in the namespace. - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ - ## - # pullSecrets: - # - myRegistrKeySecretName - -## User of the application -## ref: https://github.com/bitnami/bitnami-docker-wordpress#environment-variables -## -wordpressUsername: user - -## Application password -## Defaults to a random 10-character alphanumeric string if not set -## ref: https://github.com/bitnami/bitnami-docker-wordpress#environment-variables -## -# wordpressPassword: - -## Admin email -## ref: https://github.com/bitnami/bitnami-docker-wordpress#environment-variables -## -wordpressEmail: user@example.com - -## First name -## ref: https://github.com/bitnami/bitnami-docker-wordpress#environment-variables -## -wordpressFirstName: FirstName - -## Last name -## ref: https://github.com/bitnami/bitnami-docker-wordpress#environment-variables -## -wordpressLastName: LastName - -## Blog name -## ref: https://github.com/bitnami/bitnami-docker-wordpress#environment-variables -## -wordpressBlogName: User's Blog! - -## Table prefix -## ref: https://github.com/bitnami/bitnami-docker-wordpress#environment-variables -## -wordpressTablePrefix: wp_ - -## Set to `yes` to allow the container to be started with blank passwords -## ref: https://github.com/bitnami/bitnami-docker-wordpress#environment-variables -allowEmptyPassword: yes - -## SMTP mail delivery configuration -## ref: https://github.com/bitnami/bitnami-docker-wordpress/#smtp-configuration -## -# smtpHost: -# smtpPort: -# smtpUser: -# smtpPassword: -# smtpUsername: -# smtpProtocol: - -replicaCount: 1 - -externalDatabase: -## All of these values are only used when mariadb.enabled is set to false - ## Database host - host: localhost - - ## non-root Username for Wordpress Database - user: bn_wordpress - - ## Database password - password: "" - - ## Database name - database: bitnami_wordpress - - ## Database port number - port: 3306 - -## -## MariaDB chart configuration -## -mariadb: - ## Whether to deploy a mariadb server to satisfy the applications database requirements. To use an external database set this to false and configure the externalDatabase parameters - enabled: true - ## Disable MariaDB replication - replication: - enabled: false - - ## Create a database and a database user - ## ref: https://github.com/bitnami/bitnami-docker-mariadb/blob/master/README.md#creating-a-database-user-on-first-run - ## - db: - name: bitnami_wordpress - user: bn_wordpress - ## If the password is not specified, mariadb will generates a random password - ## - # password: - - ## MariaDB admin password - ## ref: https://github.com/bitnami/bitnami-docker-mariadb/blob/master/README.md#setting-the-root-password-on-first-run - ## - # rootUser: - # password: - - ## Enable persistence using Persistent Volume Claims - ## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ - ## - master: - persistence: - enabled: true - ## mariadb data Persistent Volume Storage Class - ## If defined, storageClassName: - ## If set to "-", storageClassName: "", which disables dynamic provisioning - ## If undefined (the default) or set to null, no storageClassName spec is - ## set, choosing the default provisioner. (gp2 on AWS, standard on - ## GKE, AWS & OpenStack) - ## - # storageClass: "-" - accessMode: ReadWriteOnce - size: 8Gi - -## Kubernetes configuration -## For minikube, set this to NodePort, elsewhere use LoadBalancer or ClusterIP -## -serviceType: LoadBalancer -## -## serviceType: NodePort -## nodePorts: -## http: -## https: -nodePorts: - http: "" - https: "" -## Enable client source IP preservation -## ref http://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip -## -serviceExternalTrafficPolicy: Cluster - -## Allow health checks to be pointed at the https port -healthcheckHttps: false - -## Configure extra options for liveness and readiness probes -## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) -livenessProbe: - initialDelaySeconds: 120 - periodSeconds: 10 - timeoutSeconds: 5 - failureThreshold: 6 - successThreshold: 1 -readinessProbe: - initialDelaySeconds: 30 - periodSeconds: 10 - timeoutSeconds: 5 - failureThreshold: 6 - successThreshold: 1 - -## Configure the ingress resource that allows you to access the -## Wordpress installation. Set up the URL -## ref: http://kubernetes.io/docs/user-guide/ingress/ -## -ingress: - ## Set to true to enable ingress record generation - enabled: false - - ## The list of hostnames to be covered with this ingress record. - ## Most likely this will be just one host, but in the event more hosts are needed, this is an array - hosts: - - name: wordpress.local - - ## Set this to true in order to enable TLS on the ingress record - ## A side effect of this will be that the backend wordpress service will be connected at port 443 - tls: false - - ## If TLS is set to true, you must declare what secret will store the key/certificate for TLS - tlsSecret: wordpress.local-tls - - ## Ingress annotations done as key:value pairs - ## If you're using kube-lego, you will want to add: - ## kubernetes.io/tls-acme: true - ## - ## For a full list of possible ingress annotations, please see - ## ref: https://github.com/kubernetes/ingress-nginx/blob/master/docs/annotations.md - ## - ## If tls is set to true, annotation ingress.kubernetes.io/secure-backends: "true" will automatically be set - annotations: - # kubernetes.io/ingress.class: nginx - # kubernetes.io/tls-acme: true - - secrets: - ## If you're providing your own certificates, please use this to add the certificates as secrets - ## key and certificate should start with -----BEGIN CERTIFICATE----- or - ## -----BEGIN RSA PRIVATE KEY----- - ## - ## name should line up with a tlsSecret set further up - ## If you're using kube-lego, this is unneeded, as it will create the secret for you if it is not set - ## - ## It is also possible to create and manage the certificates outside of this helm chart - ## Please see README.md for more information - # - name: wordpress.local-tls - # key: - # certificate: - -## Enable persistence using Persistent Volume Claims -## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ -## -persistence: - enabled: true - ## wordpress data Persistent Volume Storage Class - ## If defined, storageClassName: - ## If set to "-", storageClassName: "", which disables dynamic provisioning - ## If undefined (the default) or set to null, no storageClassName spec is - ## set, choosing the default provisioner. (gp2 on AWS, standard on - ## GKE, AWS & OpenStack) - ## - # storageClass: "-" - ## - ## If you want to reuse an existing claim, you can pass the name of the PVC using - ## the existingClaim variable - # existingClaim: your-claim - accessMode: ReadWriteOnce - size: 10Gi - -## Configure resource requests and limits -## ref: http://kubernetes.io/docs/user-guide/compute-resources/ -## -resources: - requests: - memory: 512Mi - cpu: 300m - -## Node labels for pod assignment -## Ref: https://kubernetes.io/docs/user-guide/node-selection/ -## -nodeSelector: {} - -## Tolerations for pod assignment -## Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ -## -tolerations: [] - -## Affinity for pod assignment -## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity -## -affinity: {} diff --git a/pkg/action/testdata/charts/chart-with-compressed-dependencies/.helmignore b/pkg/action/testdata/charts/chart-with-compressed-dependencies/.helmignore deleted file mode 100755 index e2cf7941f..000000000 --- a/pkg/action/testdata/charts/chart-with-compressed-dependencies/.helmignore +++ /dev/null @@ -1,5 +0,0 @@ -.git -# OWNERS file for Kubernetes -OWNERS -# example production yaml -values-production.yaml \ No newline at end of file diff --git a/pkg/action/testdata/charts/chart-with-compressed-dependencies/Chart.yaml b/pkg/action/testdata/charts/chart-with-compressed-dependencies/Chart.yaml index 602644caa..1d16590b6 100755 --- a/pkg/action/testdata/charts/chart-with-compressed-dependencies/Chart.yaml +++ b/pkg/action/testdata/charts/chart-with-compressed-dependencies/Chart.yaml @@ -1,20 +1,2 @@ -appVersion: 4.9.8 -description: Web publishing platform for building blogs and websites. -engine: gotpl -home: http://www.wordpress.com/ -icon: https://bitnami.com/assets/stacks/wordpress/img/wordpress-stack-220x234.png -keywords: -- wordpress -- cms -- blog -- http -- web -- application -- php -maintainers: -- email: containers@bitnami.com - name: bitnami-bot name: chart-with-compressed-dependencies -sources: -- https://github.com/bitnami/bitnami-docker-wordpress version: 2.1.8 diff --git a/pkg/action/testdata/charts/chart-with-compressed-dependencies/README.md b/pkg/action/testdata/charts/chart-with-compressed-dependencies/README.md deleted file mode 100755 index 3174417e0..000000000 --- a/pkg/action/testdata/charts/chart-with-compressed-dependencies/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# WordPress - -This is a testing fork of the Wordpress chart. It is not operational. diff --git a/pkg/action/testdata/charts/chart-with-compressed-dependencies/templates/NOTES.txt b/pkg/action/testdata/charts/chart-with-compressed-dependencies/templates/NOTES.txt deleted file mode 100755 index 3b94f9157..000000000 --- a/pkg/action/testdata/charts/chart-with-compressed-dependencies/templates/NOTES.txt +++ /dev/null @@ -1 +0,0 @@ -Placeholder diff --git a/pkg/action/testdata/charts/chart-with-compressed-dependencies/values.yaml b/pkg/action/testdata/charts/chart-with-compressed-dependencies/values.yaml deleted file mode 100755 index 3cb66dafd..000000000 --- a/pkg/action/testdata/charts/chart-with-compressed-dependencies/values.yaml +++ /dev/null @@ -1,254 +0,0 @@ -## Bitnami WordPress image version -## ref: https://hub.docker.com/r/bitnami/wordpress/tags/ -## -image: - registry: docker.io - repository: bitnami/wordpress - tag: 4.9.8-debian-9 - ## Specify a imagePullPolicy - ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' - ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images - ## - pullPolicy: IfNotPresent - ## Optionally specify an array of imagePullSecrets. - ## Secrets must be manually created in the namespace. - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ - ## - # pullSecrets: - # - myRegistrKeySecretName - -## User of the application -## ref: https://github.com/bitnami/bitnami-docker-wordpress#environment-variables -## -wordpressUsername: user - -## Application password -## Defaults to a random 10-character alphanumeric string if not set -## ref: https://github.com/bitnami/bitnami-docker-wordpress#environment-variables -## -# wordpressPassword: - -## Admin email -## ref: https://github.com/bitnami/bitnami-docker-wordpress#environment-variables -## -wordpressEmail: user@example.com - -## First name -## ref: https://github.com/bitnami/bitnami-docker-wordpress#environment-variables -## -wordpressFirstName: FirstName - -## Last name -## ref: https://github.com/bitnami/bitnami-docker-wordpress#environment-variables -## -wordpressLastName: LastName - -## Blog name -## ref: https://github.com/bitnami/bitnami-docker-wordpress#environment-variables -## -wordpressBlogName: User's Blog! - -## Table prefix -## ref: https://github.com/bitnami/bitnami-docker-wordpress#environment-variables -## -wordpressTablePrefix: wp_ - -## Set to `yes` to allow the container to be started with blank passwords -## ref: https://github.com/bitnami/bitnami-docker-wordpress#environment-variables -allowEmptyPassword: yes - -## SMTP mail delivery configuration -## ref: https://github.com/bitnami/bitnami-docker-wordpress/#smtp-configuration -## -# smtpHost: -# smtpPort: -# smtpUser: -# smtpPassword: -# smtpUsername: -# smtpProtocol: - -replicaCount: 1 - -externalDatabase: -## All of these values are only used when mariadb.enabled is set to false - ## Database host - host: localhost - - ## non-root Username for Wordpress Database - user: bn_wordpress - - ## Database password - password: "" - - ## Database name - database: bitnami_wordpress - - ## Database port number - port: 3306 - -## -## MariaDB chart configuration -## -mariadb: - ## Whether to deploy a mariadb server to satisfy the applications database requirements. To use an external database set this to false and configure the externalDatabase parameters - enabled: true - ## Disable MariaDB replication - replication: - enabled: false - - ## Create a database and a database user - ## ref: https://github.com/bitnami/bitnami-docker-mariadb/blob/master/README.md#creating-a-database-user-on-first-run - ## - db: - name: bitnami_wordpress - user: bn_wordpress - ## If the password is not specified, mariadb will generates a random password - ## - # password: - - ## MariaDB admin password - ## ref: https://github.com/bitnami/bitnami-docker-mariadb/blob/master/README.md#setting-the-root-password-on-first-run - ## - # rootUser: - # password: - - ## Enable persistence using Persistent Volume Claims - ## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ - ## - master: - persistence: - enabled: true - ## mariadb data Persistent Volume Storage Class - ## If defined, storageClassName: - ## If set to "-", storageClassName: "", which disables dynamic provisioning - ## If undefined (the default) or set to null, no storageClassName spec is - ## set, choosing the default provisioner. (gp2 on AWS, standard on - ## GKE, AWS & OpenStack) - ## - # storageClass: "-" - accessMode: ReadWriteOnce - size: 8Gi - -## Kubernetes configuration -## For minikube, set this to NodePort, elsewhere use LoadBalancer or ClusterIP -## -serviceType: LoadBalancer -## -## serviceType: NodePort -## nodePorts: -## http: -## https: -nodePorts: - http: "" - https: "" -## Enable client source IP preservation -## ref http://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip -## -serviceExternalTrafficPolicy: Cluster - -## Allow health checks to be pointed at the https port -healthcheckHttps: false - -## Configure extra options for liveness and readiness probes -## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) -livenessProbe: - initialDelaySeconds: 120 - periodSeconds: 10 - timeoutSeconds: 5 - failureThreshold: 6 - successThreshold: 1 -readinessProbe: - initialDelaySeconds: 30 - periodSeconds: 10 - timeoutSeconds: 5 - failureThreshold: 6 - successThreshold: 1 - -## Configure the ingress resource that allows you to access the -## Wordpress installation. Set up the URL -## ref: http://kubernetes.io/docs/user-guide/ingress/ -## -ingress: - ## Set to true to enable ingress record generation - enabled: false - - ## The list of hostnames to be covered with this ingress record. - ## Most likely this will be just one host, but in the event more hosts are needed, this is an array - hosts: - - name: wordpress.local - - ## Set this to true in order to enable TLS on the ingress record - ## A side effect of this will be that the backend wordpress service will be connected at port 443 - tls: false - - ## If TLS is set to true, you must declare what secret will store the key/certificate for TLS - tlsSecret: wordpress.local-tls - - ## Ingress annotations done as key:value pairs - ## If you're using kube-lego, you will want to add: - ## kubernetes.io/tls-acme: true - ## - ## For a full list of possible ingress annotations, please see - ## ref: https://github.com/kubernetes/ingress-nginx/blob/master/docs/annotations.md - ## - ## If tls is set to true, annotation ingress.kubernetes.io/secure-backends: "true" will automatically be set - annotations: - # kubernetes.io/ingress.class: nginx - # kubernetes.io/tls-acme: true - - secrets: - ## If you're providing your own certificates, please use this to add the certificates as secrets - ## key and certificate should start with -----BEGIN CERTIFICATE----- or - ## -----BEGIN RSA PRIVATE KEY----- - ## - ## name should line up with a tlsSecret set further up - ## If you're using kube-lego, this is unneeded, as it will create the secret for you if it is not set - ## - ## It is also possible to create and manage the certificates outside of this helm chart - ## Please see README.md for more information - # - name: wordpress.local-tls - # key: - # certificate: - -## Enable persistence using Persistent Volume Claims -## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ -## -persistence: - enabled: true - ## wordpress data Persistent Volume Storage Class - ## If defined, storageClassName: - ## If set to "-", storageClassName: "", which disables dynamic provisioning - ## If undefined (the default) or set to null, no storageClassName spec is - ## set, choosing the default provisioner. (gp2 on AWS, standard on - ## GKE, AWS & OpenStack) - ## - # storageClass: "-" - ## - ## If you want to reuse an existing claim, you can pass the name of the PVC using - ## the existingClaim variable - # existingClaim: your-claim - accessMode: ReadWriteOnce - size: 10Gi - -## Configure resource requests and limits -## ref: http://kubernetes.io/docs/user-guide/compute-resources/ -## -resources: - requests: - memory: 512Mi - cpu: 300m - -## Node labels for pod assignment -## Ref: https://kubernetes.io/docs/user-guide/node-selection/ -## -nodeSelector: {} - -## Tolerations for pod assignment -## Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ -## -tolerations: [] - -## Affinity for pod assignment -## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity -## -affinity: {} diff --git a/cmd/helm/testdata/testcharts/chart-with-no-templates-dir/Chart.yaml b/pkg/action/testdata/charts/chart-with-no-templates-dir/Chart.yaml similarity index 100% rename from cmd/helm/testdata/testcharts/chart-with-no-templates-dir/Chart.yaml rename to pkg/action/testdata/charts/chart-with-no-templates-dir/Chart.yaml diff --git a/pkg/action/testdata/charts/chart-with-schema-negative/Chart.yaml b/pkg/action/testdata/charts/chart-with-schema-negative/Chart.yaml new file mode 100644 index 000000000..395d24f6a --- /dev/null +++ b/pkg/action/testdata/charts/chart-with-schema-negative/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +description: Empty testing chart +home: https://k8s.io/helm +name: empty +sources: +- https://github.com/kubernetes/helm +version: 0.1.0 diff --git a/pkg/action/testdata/charts/chart-with-schema-negative/templates/empty.yaml b/pkg/action/testdata/charts/chart-with-schema-negative/templates/empty.yaml new file mode 100644 index 000000000..c80812f6e --- /dev/null +++ b/pkg/action/testdata/charts/chart-with-schema-negative/templates/empty.yaml @@ -0,0 +1 @@ +# This file is intentionally blank diff --git a/pkg/action/testdata/charts/chart-with-schema-negative/values.schema.json b/pkg/action/testdata/charts/chart-with-schema-negative/values.schema.json new file mode 100644 index 000000000..4df89bbe8 --- /dev/null +++ b/pkg/action/testdata/charts/chart-with-schema-negative/values.schema.json @@ -0,0 +1,67 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "addresses": { + "description": "List of addresses", + "items": { + "properties": { + "city": { + "type": "string" + }, + "number": { + "type": "number" + }, + "street": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "age": { + "description": "Age", + "minimum": 0, + "type": "integer" + }, + "employmentInfo": { + "properties": { + "salary": { + "minimum": 0, + "type": "number" + }, + "title": { + "type": "string" + } + }, + "required": [ + "salary" + ], + "type": "object" + }, + "firstname": { + "description": "First name", + "type": "string" + }, + "lastname": { + "type": "string" + }, + "likesCoffee": { + "type": "boolean" + }, + "phoneNumbers": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "firstname", + "lastname", + "addresses", + "employmentInfo" + ], + "title": "Values", + "type": "object" +} diff --git a/pkg/action/testdata/charts/chart-with-schema-negative/values.yaml b/pkg/action/testdata/charts/chart-with-schema-negative/values.yaml new file mode 100644 index 000000000..5a1250bff --- /dev/null +++ b/pkg/action/testdata/charts/chart-with-schema-negative/values.yaml @@ -0,0 +1,14 @@ +firstname: John +lastname: Doe +age: -5 +likesCoffee: true +addresses: + - city: Springfield + street: Main + number: 12345 + - city: New York + street: Broadway + number: 67890 +phoneNumbers: + - "(888) 888-8888" + - "(555) 555-5555" diff --git a/pkg/action/testdata/charts/chart-with-schema/Chart.yaml b/pkg/action/testdata/charts/chart-with-schema/Chart.yaml new file mode 100644 index 000000000..395d24f6a --- /dev/null +++ b/pkg/action/testdata/charts/chart-with-schema/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +description: Empty testing chart +home: https://k8s.io/helm +name: empty +sources: +- https://github.com/kubernetes/helm +version: 0.1.0 diff --git a/pkg/action/testdata/charts/chart-with-schema/extra-values.yaml b/pkg/action/testdata/charts/chart-with-schema/extra-values.yaml new file mode 100644 index 000000000..76c290c4f --- /dev/null +++ b/pkg/action/testdata/charts/chart-with-schema/extra-values.yaml @@ -0,0 +1,2 @@ +age: -5 +employmentInfo: null diff --git a/pkg/action/testdata/charts/chart-with-schema/templates/empty.yaml b/pkg/action/testdata/charts/chart-with-schema/templates/empty.yaml new file mode 100644 index 000000000..c80812f6e --- /dev/null +++ b/pkg/action/testdata/charts/chart-with-schema/templates/empty.yaml @@ -0,0 +1 @@ +# This file is intentionally blank diff --git a/pkg/action/testdata/charts/chart-with-schema/values.schema.json b/pkg/action/testdata/charts/chart-with-schema/values.schema.json new file mode 100644 index 000000000..4df89bbe8 --- /dev/null +++ b/pkg/action/testdata/charts/chart-with-schema/values.schema.json @@ -0,0 +1,67 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "addresses": { + "description": "List of addresses", + "items": { + "properties": { + "city": { + "type": "string" + }, + "number": { + "type": "number" + }, + "street": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "age": { + "description": "Age", + "minimum": 0, + "type": "integer" + }, + "employmentInfo": { + "properties": { + "salary": { + "minimum": 0, + "type": "number" + }, + "title": { + "type": "string" + } + }, + "required": [ + "salary" + ], + "type": "object" + }, + "firstname": { + "description": "First name", + "type": "string" + }, + "lastname": { + "type": "string" + }, + "likesCoffee": { + "type": "boolean" + }, + "phoneNumbers": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "firstname", + "lastname", + "addresses", + "employmentInfo" + ], + "title": "Values", + "type": "object" +} diff --git a/pkg/action/testdata/charts/chart-with-schema/values.yaml b/pkg/action/testdata/charts/chart-with-schema/values.yaml new file mode 100644 index 000000000..042dea664 --- /dev/null +++ b/pkg/action/testdata/charts/chart-with-schema/values.yaml @@ -0,0 +1,17 @@ +firstname: John +lastname: Doe +age: 25 +likesCoffee: true +employmentInfo: + title: Software Developer + salary: 100000 +addresses: + - city: Springfield + street: Main + number: 12345 + - city: New York + street: Broadway + number: 67890 +phoneNumbers: + - "(888) 888-8888" + - "(555) 555-5555" diff --git a/pkg/action/testdata/charts/compressedchart-0.1.0.tar.gz b/pkg/action/testdata/charts/compressedchart-0.1.0.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..3c9c24d76063d6a904405b2d6a7a84cb087f1ce4 GIT binary patch literal 477 zcmV<30V4h%iwG0|00000|0w_~VMtOiV@ORlOnEsqVl!4SWK%V1T2nbTPgYhoO;>Dc zVQyr3R8em|NM&qo0PL4vi_<_5!26s}F{UjHhD>x0Xejw~|-egB1QU=&JEdrHEIt>CEtv%dd}n=<=92zSKn;o(8OM@#S> zYFc5(0#_R!xxRXQ%zfa$rtiOMiLGgzk94**j`?3M7Jt0|r`i8O7{f;tq39Bbhr@%1 zO-l}zo#EQJ1_D-Jv7w}jF??!Gg4BiJqa;WzF+;Dc zVQyr3R8em|NM&qo0PL4vi_<_5!26s}F{UjHhD>x0Xejw~|-egB1QU=&JEdrHEIt>CEtv%dd}n=<=92zSKn;o(8OM@#S> zYFc5(0#_R!xxRXQ%zfa$rtiOMiLGgzk94**j`?3M7Jt0|r`i8O7{f;tq39Bbhr@%1 zO-l}zo#EQJ1_D-Jv7w}jF??!Gg4BiJqa;WzF+;Dc zVQyr3R8em|NM&qo0PL4vi_<_5!26s}F)eG5__n?E62T&$9nR zaPZh}uYVQ7^}*#!N0u3azW+itFbbuoJtg79R&dn+S>OM~O_}{4ggavP@bIACqb2wb zHLb8?fvb&=Twgst=05OW)AwJs#MU&^XY$NVoBi$C7~)9n8sjNv1SP;?2z!{Nch zrX>f<&Tws90|BeA*icf%7(TToLFz*AQ4*wspoCYeko Tb2>i)00960YK^g$02BZKS`FmP literal 0 HcmV?d00001 diff --git a/pkg/action/testdata/charts/compressedchart-0.3.0.tgz b/pkg/action/testdata/charts/compressedchart-0.3.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..051bd6fd9a030a3f4327e8002a8912c1f5f68050 GIT binary patch literal 477 zcmV<30V4h%iwG0|00000|0w_~VMtOiV@ORlOnEsqVl!4SWK%V1T2nbTPgYhoO;>Dc zVQyr3R8em|NM&qo0PL4vi_<_5!26s}Fj!(#55d%N%6r{|dRMblL`R$bVgxL;q*9Y4-md z>^-)d>tBU%y?6Q2k!8-o(0?Ht7=_Z)o|156D>&%?bm;&5rp*4Ig*#&Q@bIACqb2wb z4K1-}fvdHT++00A=05OWGxT3|#MZRVM>^RWhx{++^FQAIRrdcZjNv1SP;?2z!~Vg; zx+4dR-f&}F3jyn|*iur(7(R6-LFz;BQ4*w%n4x9A0E<$0#EPK51s@!5z`Na*+mIko1U8OTq2AtqxfdU)P_4<|CYeko Tb38u+00960Q~zm}02BZK0h8&p literal 0 HcmV?d00001 diff --git a/pkg/action/testdata/charts/compressedchart-with-hyphens-0.1.0.tgz b/pkg/action/testdata/charts/compressedchart-with-hyphens-0.1.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..379210a92c1795429d2c4baae389f1e971f26824 GIT binary patch literal 548 zcmV+<0^9u`iwG0|00000|0w_~VMtOiV@ORlOnEsqVl!4SWK%V1T2nbTPgYhoO;>Dc zVQyr3R8em|NM&qo0PL4fi`y^|#dG$jc->rDXjD0A64=|)92WW)wwIoYVoz*QSrU?* zG;H^~7dcDXrjTqgP3fZFMMBsbi zPWu0B_M89nr2n%p#E0nPPIpGV%QZGNX)If*N~tSYQG5|qH0t|nfN!leE_nEwltQJ< z5{(E&Ep_!Aj+6*;9W6i9KdlR0WlY0RR8Xa#gbc6aWCh@%&~0 literal 0 HcmV?d00001 diff --git a/cmd/helm/testdata/testcharts/corrupted-compressed-chart.tgz b/pkg/action/testdata/charts/corrupted-compressed-chart.tgz similarity index 100% rename from cmd/helm/testdata/testcharts/corrupted-compressed-chart.tgz rename to pkg/action/testdata/charts/corrupted-compressed-chart.tgz diff --git a/cmd/helm/testdata/testcharts/decompressedchart/Chart.yaml b/pkg/action/testdata/charts/decompressedchart/Chart.yaml similarity index 100% rename from cmd/helm/testdata/testcharts/decompressedchart/Chart.yaml rename to pkg/action/testdata/charts/decompressedchart/Chart.yaml diff --git a/cmd/helm/testdata/testcharts/decompressedchart/values.yaml b/pkg/action/testdata/charts/decompressedchart/values.yaml similarity index 100% rename from cmd/helm/testdata/testcharts/decompressedchart/values.yaml rename to pkg/action/testdata/charts/decompressedchart/values.yaml diff --git a/cmd/helm/testdata/testcharts/multiplecharts-lint-chart-1/Chart.yaml b/pkg/action/testdata/charts/multiplecharts-lint-chart-1/Chart.yaml similarity index 100% rename from cmd/helm/testdata/testcharts/multiplecharts-lint-chart-1/Chart.yaml rename to pkg/action/testdata/charts/multiplecharts-lint-chart-1/Chart.yaml diff --git a/cmd/helm/testdata/testcharts/multiplecharts-lint-chart-1/templates/configmap.yaml b/pkg/action/testdata/charts/multiplecharts-lint-chart-1/templates/configmap.yaml similarity index 100% rename from cmd/helm/testdata/testcharts/multiplecharts-lint-chart-1/templates/configmap.yaml rename to pkg/action/testdata/charts/multiplecharts-lint-chart-1/templates/configmap.yaml diff --git a/cmd/helm/testdata/testcharts/multiplecharts-lint-chart-1/values.yaml b/pkg/action/testdata/charts/multiplecharts-lint-chart-1/values.yaml similarity index 100% rename from cmd/helm/testdata/testcharts/multiplecharts-lint-chart-1/values.yaml rename to pkg/action/testdata/charts/multiplecharts-lint-chart-1/values.yaml diff --git a/cmd/helm/testdata/testcharts/multiplecharts-lint-chart-2/Chart.yaml b/pkg/action/testdata/charts/multiplecharts-lint-chart-2/Chart.yaml similarity index 100% rename from cmd/helm/testdata/testcharts/multiplecharts-lint-chart-2/Chart.yaml rename to pkg/action/testdata/charts/multiplecharts-lint-chart-2/Chart.yaml diff --git a/cmd/helm/testdata/testcharts/multiplecharts-lint-chart-2/templates/configmap.yaml b/pkg/action/testdata/charts/multiplecharts-lint-chart-2/templates/configmap.yaml similarity index 100% rename from cmd/helm/testdata/testcharts/multiplecharts-lint-chart-2/templates/configmap.yaml rename to pkg/action/testdata/charts/multiplecharts-lint-chart-2/templates/configmap.yaml diff --git a/cmd/helm/testdata/testcharts/multiplecharts-lint-chart-2/values.yaml b/pkg/action/testdata/charts/multiplecharts-lint-chart-2/values.yaml similarity index 100% rename from cmd/helm/testdata/testcharts/multiplecharts-lint-chart-2/values.yaml rename to pkg/action/testdata/charts/multiplecharts-lint-chart-2/values.yaml diff --git a/pkg/action/testdata/charts/pre-release-chart-0.1.0-alpha.tgz b/pkg/action/testdata/charts/pre-release-chart-0.1.0-alpha.tgz new file mode 100644 index 0000000000000000000000000000000000000000..5d5770fed227de5f776eb9080eb377aad6293c1b GIT binary patch literal 355 zcmV-p0i6CHiwG0|00000|0w_~VMtOiV@ORlOnEsqVl!4SWK%V1T2nbTPgYhoO;>Dc zVQyr3R8em|NM&qo0PK{zYV$x4g;nb*23$-3NWU)N&csC^NtY(&SQ_DlU9Ff|8T|G^ za%V#lh=@thS7=o1ZFbK&gK#2jnUs^}ND}@%OyBfO&PEG?h*+29ToLiQVwP7?_P@yL zI1Ma8b~7i_FmV`{SsQ%M$8b5@3*jnN45@T9YE&=p2h=9&w(}W z$?+C$9uN+r2y|ofk(Ta0{KWJPp`$V@VjMq`0UE1~Q@$ zJRGL~X*n=`@No8{Kwvjm3an`imvnLG Date: Sun, 15 Dec 2019 20:13:56 +0530 Subject: [PATCH 42/66] Show errors when linting for Chart.yaml version and appVersion fields of type non-string Signed-off-by: Karuppiah Natarajan --- .../multiplecharts-lint-chart-1/Chart.yaml | 2 +- .../multiplecharts-lint-chart-2/Chart.yaml | 2 +- pkg/lint/rules/chartfile.go | 42 ++++++++++ pkg/lint/rules/chartfile_test.go | 78 +++++++++++++------ .../testdata/anotherbadchartfile/Chart.yaml | 15 ++++ 5 files changed, 112 insertions(+), 27 deletions(-) create mode 100644 pkg/lint/rules/testdata/anotherbadchartfile/Chart.yaml diff --git a/pkg/action/testdata/charts/multiplecharts-lint-chart-1/Chart.yaml b/pkg/action/testdata/charts/multiplecharts-lint-chart-1/Chart.yaml index 3b342ae4f..e33c97e8c 100644 --- a/pkg/action/testdata/charts/multiplecharts-lint-chart-1/Chart.yaml +++ b/pkg/action/testdata/charts/multiplecharts-lint-chart-1/Chart.yaml @@ -1,4 +1,4 @@ apiVersion: v1 name: multiplecharts-lint-chart-1 -version: 1 +version: "1" icon: "" \ No newline at end of file diff --git a/pkg/action/testdata/charts/multiplecharts-lint-chart-2/Chart.yaml b/pkg/action/testdata/charts/multiplecharts-lint-chart-2/Chart.yaml index bd101d808..b27de2754 100644 --- a/pkg/action/testdata/charts/multiplecharts-lint-chart-2/Chart.yaml +++ b/pkg/action/testdata/charts/multiplecharts-lint-chart-2/Chart.yaml @@ -1,4 +1,4 @@ apiVersion: v1 name: multiplecharts-lint-chart-2 -version: 1 +version: "1" icon: "" \ No newline at end of file diff --git a/pkg/lint/rules/chartfile.go b/pkg/lint/rules/chartfile.go index 91a64fe13..b49f2cec0 100644 --- a/pkg/lint/rules/chartfile.go +++ b/pkg/lint/rules/chartfile.go @@ -18,12 +18,14 @@ package rules // import "helm.sh/helm/v3/pkg/lint/rules" import ( "fmt" + "io/ioutil" "os" "path/filepath" "github.com/Masterminds/semver/v3" "github.com/asaskevich/govalidator" "github.com/pkg/errors" + "sigs.k8s.io/yaml" "helm.sh/helm/v3/pkg/chart" "helm.sh/helm/v3/pkg/chartutil" @@ -45,11 +47,18 @@ func Chartfile(linter *support.Linter) { return } + // type check for Chart.yaml . ignoring error as any parse + // errors would already be caught in the above load function + chartFileForTypeCheck, _ := loadChartFileForTypeCheck(chartPath) + linter.RunLinterRule(support.ErrorSev, chartFileName, validateChartName(chartFile)) // Chart metadata linter.RunLinterRule(support.ErrorSev, chartFileName, validateChartAPIVersion(chartFile)) + + linter.RunLinterRule(support.ErrorSev, chartFileName, validateChartVersionType(chartFileForTypeCheck)) linter.RunLinterRule(support.ErrorSev, chartFileName, validateChartVersion(chartFile)) + linter.RunLinterRule(support.ErrorSev, chartFileName, validateChartAppVersionType(chartFileForTypeCheck)) linter.RunLinterRule(support.ErrorSev, chartFileName, validateChartMaintainer(chartFile)) linter.RunLinterRule(support.ErrorSev, chartFileName, validateChartSources(chartFile)) linter.RunLinterRule(support.InfoSev, chartFileName, validateChartIconPresence(chartFile)) @@ -58,6 +67,26 @@ func Chartfile(linter *support.Linter) { linter.RunLinterRule(support.ErrorSev, chartFileName, validateChartDependencies(chartFile)) } +func validateChartVersionType(data map[string]interface{}) error { + return isStringValue(data, "version") +} + +func validateChartAppVersionType(data map[string]interface{}) error { + return isStringValue(data, "appVersion") +} + +func isStringValue(data map[string]interface{}, key string) error { + value, ok := data[key] + if !ok { + return nil + } + valueType := fmt.Sprintf("%T", value) + if valueType != "string" { + return errors.Errorf("%s should be of type string but it's of type %s", key, valueType) + } + return nil +} + func validateChartYamlNotDirectory(chartPath string) error { fi, err := os.Stat(chartPath) @@ -166,3 +195,16 @@ func validateChartType(cf *chart.Metadata) error { } return nil } + +// loadChartFileForTypeCheck loads the Chart.yaml +// in a generic form of a map[string]interface{}, so that the type +// of the values can be checked +func loadChartFileForTypeCheck(filename string) (map[string]interface{}, error) { + b, err := ioutil.ReadFile(filename) + if err != nil { + return nil, err + } + y := make(map[string]interface{}) + err = yaml.Unmarshal(b, &y) + return y, err +} diff --git a/pkg/lint/rules/chartfile_test.go b/pkg/lint/rules/chartfile_test.go index d032dd12f..087cda047 100644 --- a/pkg/lint/rules/chartfile_test.go +++ b/pkg/lint/rules/chartfile_test.go @@ -30,7 +30,8 @@ import ( ) const ( - badChartDir = "testdata/badchartfile" + badChartDir = "testdata/badchartfile" + anotherBadChartDir = "testdata/anotherbadchartfile" ) var ( @@ -184,36 +185,63 @@ func TestValidateChartIconURL(t *testing.T) { } func TestChartfile(t *testing.T) { - linter := support.Linter{ChartDir: badChartDir} - Chartfile(&linter) - msgs := linter.Messages + t.Run("Chart.yaml basic validity issues", func(t *testing.T) { + linter := support.Linter{ChartDir: badChartDir} + Chartfile(&linter) + msgs := linter.Messages + expectedNumberOfErrorMessages := 6 + + if len(msgs) != expectedNumberOfErrorMessages { + t.Errorf("Expected %d errors, got %d", expectedNumberOfErrorMessages, len(msgs)) + return + } - if len(msgs) != 6 { - t.Errorf("Expected 6 errors, got %d", len(msgs)) - } + if !strings.Contains(msgs[0].Err.Error(), "name is required") { + t.Errorf("Unexpected message 0: %s", msgs[0].Err) + } - if !strings.Contains(msgs[0].Err.Error(), "name is required") { - t.Errorf("Unexpected message 0: %s", msgs[0].Err) - } + if !strings.Contains(msgs[1].Err.Error(), "apiVersion is required. The value must be either \"v1\" or \"v2\"") { + t.Errorf("Unexpected message 1: %s", msgs[1].Err) + } - if !strings.Contains(msgs[1].Err.Error(), "apiVersion is required. The value must be either \"v1\" or \"v2\"") { - t.Errorf("Unexpected message 1: %s", msgs[1].Err) - } + if !strings.Contains(msgs[2].Err.Error(), "version '0.0.0.0' is not a valid SemVer") { + t.Errorf("Unexpected message 2: %s", msgs[2].Err) + } - if !strings.Contains(msgs[2].Err.Error(), "version '0.0.0.0' is not a valid SemVer") { - t.Errorf("Unexpected message 2: %s", msgs[2].Err) - } + if !strings.Contains(msgs[3].Err.Error(), "icon is recommended") { + t.Errorf("Unexpected message 3: %s", msgs[3].Err) + } - if !strings.Contains(msgs[3].Err.Error(), "icon is recommended") { - t.Errorf("Unexpected message 3: %s", msgs[3].Err) - } + if !strings.Contains(msgs[4].Err.Error(), "chart type is not valid in apiVersion") { + t.Errorf("Unexpected message 4: %s", msgs[4].Err) + } - if !strings.Contains(msgs[4].Err.Error(), "chart type is not valid in apiVersion") { - t.Errorf("Unexpected message 4: %s", msgs[4].Err) - } + if !strings.Contains(msgs[5].Err.Error(), "dependencies are not valid in the Chart file with apiVersion") { + t.Errorf("Unexpected message 5: %s", msgs[5].Err) + } + }) - if !strings.Contains(msgs[5].Err.Error(), "dependencies are not valid in the Chart file with apiVersion") { - t.Errorf("Unexpected message 5: %s", msgs[5].Err) - } + t.Run("Chart.yaml validity issues due to type mismatch", func(t *testing.T) { + linter := support.Linter{ChartDir: anotherBadChartDir} + Chartfile(&linter) + msgs := linter.Messages + expectedNumberOfErrorMessages := 3 + + if len(msgs) != expectedNumberOfErrorMessages { + t.Errorf("Expected %d errors, got %d", expectedNumberOfErrorMessages, len(msgs)) + return + } + if !strings.Contains(msgs[0].Err.Error(), "version should be of type string") { + t.Errorf("Unexpected message 0: %s", msgs[0].Err) + } + + if !strings.Contains(msgs[1].Err.Error(), "version '7.2445e+06' is not a valid SemVer") { + t.Errorf("Unexpected message 1: %s", msgs[1].Err) + } + + if !strings.Contains(msgs[2].Err.Error(), "appVersion should be of type string") { + t.Errorf("Unexpected message 2: %s", msgs[2].Err) + } + }) } diff --git a/pkg/lint/rules/testdata/anotherbadchartfile/Chart.yaml b/pkg/lint/rules/testdata/anotherbadchartfile/Chart.yaml new file mode 100644 index 000000000..7f3cab390 --- /dev/null +++ b/pkg/lint/rules/testdata/anotherbadchartfile/Chart.yaml @@ -0,0 +1,15 @@ +name: "some-chart" +apiVersion: v2 +description: A Helm chart for Kubernetes +version: 72445e2 +home: "" +type: application +appVersion: 72225e2 +icon: "https://some-url.com/icon.jpeg" +dependencies: + - name: mariadb + version: 5.x.x + repository: https://kubernetes-charts.storage.googleapis.com/ + condition: mariadb.enabled + tags: + - database From a0fd1d81f03aaabbd961f0bfd0dfd907493078c6 Mon Sep 17 00:00:00 2001 From: Peter Engelbert Date: Thu, 28 May 2020 13:44:43 -0500 Subject: [PATCH 43/66] Fix crashing `helm chart list` with large list With a large list of charts, `helm chart list` will crash with the following message: ``` $ helm chart list --debug Error: open /home/me/.cache/helm/registry/cache/blobs/sha256/109971e44d63f7fd11fff60d19db41c2429a136943be2e3f8fd3e4c165156536: too many open files helm.go:75: [debug] open /home/me/.cache/helm/registry/cache/blobs/sha256/109971e44d63f7fd11fff60d19db41c2429a136943be2e3f8fd3e4c165156536: too many open files ``` Signed-off-by: Peter Engelbert --- internal/experimental/registry/cache.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/experimental/registry/cache.go b/internal/experimental/registry/cache.go index fbd62562a..5aca63668 100644 --- a/internal/experimental/registry/cache.go +++ b/internal/experimental/registry/cache.go @@ -357,6 +357,8 @@ func (cache *Cache) fetchBlob(desc *ocispec.Descriptor) ([]byte, error) { if err != nil { return nil, err } + defer reader.Close() + bytes := make([]byte, desc.Size) _, err = reader.ReadAt(bytes, 0) if err != nil { From 7dec5dcb8e2857dd14d0ea43f1c68876b5ac8a2d Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Fri, 29 May 2020 15:54:42 -0400 Subject: [PATCH 44/66] chore(helm): Avoid confusion in command usage Having both the `showCmd` and the `subCmd` passed to `addShowFlags()` can easily lead to mistakes in using the wrong command. Instead, `addShowFlags()` should only focus on the `subCmd` Signed-off-by: Marc Khouzam --- cmd/helm/show.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/helm/show.go b/cmd/helm/show.go index b335c5f76..91c35a53c 100644 --- a/cmd/helm/show.go +++ b/cmd/helm/show.go @@ -136,7 +136,8 @@ func newShowCmd(out io.Writer) *cobra.Command { cmds := []*cobra.Command{all, readmeSubCmd, valuesSubCmd, chartSubCmd} for _, subCmd := range cmds { - addShowFlags(showCommand, subCmd, client) + addShowFlags(subCmd, client) + showCommand.AddCommand(subCmd) // Register the completion function for each subcommand completion.RegisterValidArgsFunc(subCmd, validArgsFunc) @@ -145,12 +146,11 @@ func newShowCmd(out io.Writer) *cobra.Command { return showCommand } -func addShowFlags(showCmd *cobra.Command, subCmd *cobra.Command, client *action.Show) { +func addShowFlags(subCmd *cobra.Command, client *action.Show) { f := subCmd.Flags() f.BoolVar(&client.Devel, "devel", false, "use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored") addChartPathOptionsFlags(f, &client.ChartPathOptions) - showCmd.AddCommand(subCmd) } func runShow(args []string, client *action.Show) (string, error) { From f11e74ee571f6a21ea5fd647513324d7268ff8d3 Mon Sep 17 00:00:00 2001 From: Peter Engelbert Date: Wed, 3 Jun 2020 15:23:26 -0500 Subject: [PATCH 45/66] Add unit test for man-in-the-middle attack on pull Add a unit test that proves the digest of the received content being checked. The check should ensure that the digest of the received content is identical to the digest provided by the manifest in the layers[0] descriptor. This check is currently implemented in containerd, so the unit test ensures security in the case a breaking change is made in containerd. Signed-off-by: Peter Engelbert --- internal/experimental/registry/client_test.go | 66 +++++++++++++++++-- 1 file changed, 62 insertions(+), 4 deletions(-) diff --git a/internal/experimental/registry/client_test.go b/internal/experimental/registry/client_test.go index 6e9d5db36..2d208b7b9 100644 --- a/internal/experimental/registry/client_test.go +++ b/internal/experimental/registry/client_test.go @@ -24,11 +24,16 @@ import ( "io/ioutil" "net" "net/http" + "net/http/httptest" + "net/url" "os" "path/filepath" + "strings" "testing" "time" + "github.com/containerd/containerd/errdefs" + auth "github.com/deislabs/oras/pkg/auth/docker" "github.com/docker/distribution/configuration" "github.com/docker/distribution/registry" @@ -49,10 +54,11 @@ var ( type RegistryClientTestSuite struct { suite.Suite - Out io.Writer - DockerRegistryHost string - CacheRootDir string - RegistryClient *Client + Out io.Writer + DockerRegistryHost string + CompromisedRegistryHost string + CacheRootDir string + RegistryClient *Client } func (suite *RegistryClientTestSuite) SetupSuite() { @@ -116,6 +122,8 @@ func (suite *RegistryClientTestSuite) SetupSuite() { dockerRegistry, err := registry.NewRegistry(context.Background(), config) suite.Nil(err, "no error creating test registry") + suite.CompromisedRegistryHost = initCompromisedRegistryTestServer() + // Start Docker registry go dockerRegistry.ListenAndServe() } @@ -232,6 +240,16 @@ func (suite *RegistryClientTestSuite) Test_7_Logout() { suite.Nil(err, "no error logging out of registry") } +func (suite *RegistryClientTestSuite) Test_8_ManInTheMiddle() { + ref, err := ParseReference(fmt.Sprintf("%s/testrepo/supposedlysafechart:9.9.9", suite.CompromisedRegistryHost)) + suite.Nil(err) + + // returns content that does not match the expected digest + err = suite.RegistryClient.PullChart(ref) + suite.NotNil(err) + suite.True(errdefs.IsFailedPrecondition(err)) +} + func TestRegistryClientTestSuite(t *testing.T) { suite.Run(t, new(RegistryClientTestSuite)) } @@ -250,3 +268,43 @@ func getFreePort() (int, error) { defer l.Close() return l.Addr().(*net.TCPAddr).Port, nil } + +func initCompromisedRegistryTestServer() string { + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if strings.Contains(r.URL.Path, "manifests") { + w.Header().Set("Content-Type", "application/vnd.oci.image.manifest.v1+json") + w.WriteHeader(200) + + // layers[0] is the blob []byte("a") + w.Write([]byte( + `{ "schemaVersion": 2, "config": { + "mediaType": "application/vnd.cncf.helm.config.v1+json", + "digest": "sha256:a705ee2789ab50a5ba20930f246dbd5cc01ff9712825bb98f57ee8414377f133", + "size": 181 + }, + "layers": [ + { + "mediaType": "application/tar+gzip", + "digest": "sha256:ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb", + "size": 1 + } + ] +}`)) + } else if r.URL.Path == "/v2/testrepo/supposedlysafechart/blobs/sha256:a705ee2789ab50a5ba20930f246dbd5cc01ff9712825bb98f57ee8414377f133" { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + w.Write([]byte("{\"name\":\"mychart\",\"version\":\"0.1.0\",\"description\":\"A Helm chart for Kubernetes\\n" + + "an 'application' or a 'library' chart.\",\"apiVersion\":\"v2\",\"appVersion\":\"1.16.0\",\"type\":" + + "\"application\"}")) + } else if r.URL.Path == "/v2/testrepo/supposedlysafechart/blobs/sha256:ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb" { + w.Header().Set("Content-Type", "application/tar+gzip") + w.WriteHeader(200) + w.Write([]byte("b")) + } else { + w.WriteHeader(500) + } + })) + + u, _ := url.Parse(s.URL) + return fmt.Sprintf("localhost:%s", u.Port()) +} From 562767b04015546e53677bb3c8aa5cae12897fa3 Mon Sep 17 00:00:00 2001 From: wawa0210 Date: Tue, 9 Jun 2020 17:49:02 +0800 Subject: [PATCH 46/66] Fix description is ignore when installed with upgrade Signed-off-by: wawa0210 --- cmd/helm/upgrade.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/helm/upgrade.go b/cmd/helm/upgrade.go index c263d32e7..f8103b485 100644 --- a/cmd/helm/upgrade.go +++ b/cmd/helm/upgrade.go @@ -100,6 +100,7 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { instClient.PostRenderer = client.PostRenderer instClient.DisableOpenAPIValidation = client.DisableOpenAPIValidation instClient.SubNotes = client.SubNotes + instClient.Description = client.Description rel, err := runInstall(args, instClient, valueOpts, out) if err != nil { From e09e8604e6160775890c154b1fb8b6683a8bbb6f Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Fri, 29 May 2020 14:58:52 -0400 Subject: [PATCH 47/66] fix(doc): generic description for --version/verify The flags added by addChartPathOptionsFlags() are used for `helm install` and `helm upgrade` but also for `helm template`, `helm show` and `helm pull`. Because of the latter three, we should not use the word 'install' in the description of the --version and --verify flags. Signed-off-by: Marc Khouzam --- cmd/helm/flags.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/helm/flags.go b/cmd/helm/flags.go index 246cb0dd5..6b9c3050b 100644 --- a/cmd/helm/flags.go +++ b/cmd/helm/flags.go @@ -41,8 +41,8 @@ func addValueOptionsFlags(f *pflag.FlagSet, v *values.Options) { } func addChartPathOptionsFlags(f *pflag.FlagSet, c *action.ChartPathOptions) { - f.StringVar(&c.Version, "version", "", "specify the exact chart version to install. If this is not specified, the latest version is installed") - f.BoolVar(&c.Verify, "verify", false, "verify the package before installing it") + f.StringVar(&c.Version, "version", "", "specify the exact chart version to use. If this is not specified, the latest version is used") + f.BoolVar(&c.Verify, "verify", false, "verify the package before using it") f.StringVar(&c.Keyring, "keyring", defaultKeyring(), "location of public keys used for verification") f.StringVar(&c.RepoURL, "repo", "", "chart repository url where to locate the requested chart") f.StringVar(&c.Username, "username", "", "chart repository username where to locate the requested chart") From 88a3d6eaea65971b3e4884b5abbcccc4d7a79f72 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Sat, 11 Apr 2020 14:06:56 -0400 Subject: [PATCH 48/66] feat(comp): Move custom completions to Cobra 1.0 Cobra 1.0 introduces custom Go completions. This commit replaces Helm's own solution to use Cobra's solution. This allows to completely remove Helm's internal "completion" package. Signed-off-by: Marc Khouzam --- cmd/helm/flags.go | 13 +- cmd/helm/get_all.go | 25 +- cmd/helm/get_hooks.go | 28 +- cmd/helm/get_manifest.go | 28 +- cmd/helm/get_notes.go | 25 +- cmd/helm/get_values.go | 26 +- cmd/helm/history.go | 21 +- cmd/helm/install.go | 13 +- cmd/helm/list.go | 9 +- cmd/helm/load_plugins.go | 22 +- cmd/helm/plugin_uninstall.go | 16 +- cmd/helm/plugin_update.go | 16 +- cmd/helm/pull.go | 15 +- cmd/helm/release_testing.go | 15 +- cmd/helm/repo_remove.go | 10 +- cmd/helm/rollback.go | 15 +- cmd/helm/root.go | 40 +- cmd/helm/search_repo.go | 23 +- cmd/helm/show.go | 44 +- cmd/helm/status.go | 26 +- cmd/helm/template.go | 9 +- cmd/helm/testdata/output/output-comp.txt | 1 + cmd/helm/testdata/output/plugin_args_comp.txt | 1 + .../testdata/output/plugin_args_flag_comp.txt | 1 + .../output/plugin_args_many_args_comp.txt | 1 + .../testdata/output/plugin_args_ns_comp.txt | 1 + .../output/plugin_echo_bad_directive.txt | 1 + .../output/plugin_echo_no_directive.txt | 1 + cmd/helm/testdata/output/revision-comp.txt | 1 + .../output/revision-wrong-args-comp.txt | 1 + cmd/helm/testdata/output/status-comp.txt | 1 + .../output/status-wrong-args-comp.txt | 1 + cmd/helm/uninstall.go | 15 +- cmd/helm/upgrade.go | 21 +- internal/completion/complete.go | 399 ------------------ 35 files changed, 235 insertions(+), 650 deletions(-) delete mode 100644 internal/completion/complete.go diff --git a/cmd/helm/flags.go b/cmd/helm/flags.go index 6b9c3050b..d4cd88fef 100644 --- a/cmd/helm/flags.go +++ b/cmd/helm/flags.go @@ -18,12 +18,12 @@ package main import ( "fmt" + "log" "strings" "github.com/spf13/cobra" "github.com/spf13/pflag" - "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/cli/output" "helm.sh/helm/v3/pkg/cli/values" @@ -55,19 +55,22 @@ func addChartPathOptionsFlags(f *pflag.FlagSet, c *action.ChartPathOptions) { // bindOutputFlag will add the output flag to the given command and bind the // value to the given format pointer func bindOutputFlag(cmd *cobra.Command, varRef *output.Format) { - f := cmd.Flags() - flag := f.VarPF(newOutputValue(output.Table, varRef), outputFlag, "o", + cmd.Flags().VarP(newOutputValue(output.Table, varRef), outputFlag, "o", fmt.Sprintf("prints the output in the specified format. Allowed values: %s", strings.Join(output.Formats(), ", "))) - completion.RegisterFlagCompletionFunc(flag, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + err := cmd.RegisterFlagCompletionFunc(outputFlag, func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { var formatNames []string for _, format := range output.Formats() { if strings.HasPrefix(format, toComplete) { formatNames = append(formatNames, format) } } - return formatNames, completion.BashCompDirectiveDefault + return formatNames, cobra.ShellCompDirectiveDefault }) + + if err != nil { + log.Fatal(err) + } } type outputValue output.Format diff --git a/cmd/helm/get_all.go b/cmd/helm/get_all.go index 7d893d7e0..1ebc7e387 100644 --- a/cmd/helm/get_all.go +++ b/cmd/helm/get_all.go @@ -18,11 +18,11 @@ package main import ( "io" + "log" "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/require" - "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/cli/output" ) @@ -41,6 +41,12 @@ func newGetAllCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { Short: "download all information for a named release", Long: getAllHelp, Args: require.ExactArgs(1), + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) != 0 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + return compListReleases(toComplete, cfg) + }, RunE: func(cmd *cobra.Command, args []string) error { res, err := client.Run(args[0]) if err != nil { @@ -57,24 +63,19 @@ func newGetAllCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { }, } - // Function providing dynamic auto-completion - completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { - if len(args) != 0 { - return nil, completion.BashCompDirectiveNoFileComp - } - return compListReleases(toComplete, cfg) - }) - f := cmd.Flags() f.IntVar(&client.Version, "revision", 0, "get the named release with revision") - flag := f.Lookup("revision") - completion.RegisterFlagCompletionFunc(flag, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + err := cmd.RegisterFlagCompletionFunc("revision", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if len(args) == 1 { return compListRevisions(cfg, args[0]) } - return nil, completion.BashCompDirectiveNoFileComp + return nil, cobra.ShellCompDirectiveNoFileComp }) + if err != nil { + log.Fatal(err) + } + f.StringVar(&template, "template", "", "go template for formatting the output, eg: {{.Release.Name}}") return cmd diff --git a/cmd/helm/get_hooks.go b/cmd/helm/get_hooks.go index c2087b1ba..6453c30eb 100644 --- a/cmd/helm/get_hooks.go +++ b/cmd/helm/get_hooks.go @@ -19,11 +19,11 @@ package main import ( "fmt" "io" + "log" "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/require" - "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/action" ) @@ -41,6 +41,12 @@ func newGetHooksCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { Short: "download all hooks for a named release", Long: getHooksHelp, Args: require.ExactArgs(1), + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) != 0 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + return compListReleases(toComplete, cfg) + }, RunE: func(cmd *cobra.Command, args []string) error { res, err := client.Run(args[0]) if err != nil { @@ -53,23 +59,17 @@ func newGetHooksCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { }, } - // Function providing dynamic auto-completion - completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { - if len(args) != 0 { - return nil, completion.BashCompDirectiveNoFileComp - } - return compListReleases(toComplete, cfg) - }) - - f := cmd.Flags() - f.IntVar(&client.Version, "revision", 0, "get the named release with revision") - flag := f.Lookup("revision") - completion.RegisterFlagCompletionFunc(flag, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + cmd.Flags().IntVar(&client.Version, "revision", 0, "get the named release with revision") + err := cmd.RegisterFlagCompletionFunc("revision", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if len(args) == 1 { return compListRevisions(cfg, args[0]) } - return nil, completion.BashCompDirectiveNoFileComp + return nil, cobra.ShellCompDirectiveNoFileComp }) + if err != nil { + log.Fatal(err) + } + return cmd } diff --git a/cmd/helm/get_manifest.go b/cmd/helm/get_manifest.go index f332befd9..048bf36b0 100644 --- a/cmd/helm/get_manifest.go +++ b/cmd/helm/get_manifest.go @@ -19,11 +19,11 @@ package main import ( "fmt" "io" + "log" "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/require" - "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/action" ) @@ -43,6 +43,12 @@ func newGetManifestCmd(cfg *action.Configuration, out io.Writer) *cobra.Command Short: "download the manifest for a named release", Long: getManifestHelp, Args: require.ExactArgs(1), + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) != 0 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + return compListReleases(toComplete, cfg) + }, RunE: func(cmd *cobra.Command, args []string) error { res, err := client.Run(args[0]) if err != nil { @@ -53,23 +59,17 @@ func newGetManifestCmd(cfg *action.Configuration, out io.Writer) *cobra.Command }, } - // Function providing dynamic auto-completion - completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { - if len(args) != 0 { - return nil, completion.BashCompDirectiveNoFileComp - } - return compListReleases(toComplete, cfg) - }) - - f := cmd.Flags() - f.IntVar(&client.Version, "revision", 0, "get the named release with revision") - flag := f.Lookup("revision") - completion.RegisterFlagCompletionFunc(flag, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + cmd.Flags().IntVar(&client.Version, "revision", 0, "get the named release with revision") + err := cmd.RegisterFlagCompletionFunc("revision", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if len(args) == 1 { return compListRevisions(cfg, args[0]) } - return nil, completion.BashCompDirectiveNoFileComp + return nil, cobra.ShellCompDirectiveNoFileComp }) + if err != nil { + log.Fatal(err) + } + return cmd } diff --git a/cmd/helm/get_notes.go b/cmd/helm/get_notes.go index 4491bd9ba..88d494fc4 100644 --- a/cmd/helm/get_notes.go +++ b/cmd/helm/get_notes.go @@ -19,11 +19,11 @@ package main import ( "fmt" "io" + "log" "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/require" - "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/action" ) @@ -39,6 +39,12 @@ func newGetNotesCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { Short: "download the notes for a named release", Long: getNotesHelp, Args: require.ExactArgs(1), + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) != 0 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + return compListReleases(toComplete, cfg) + }, RunE: func(cmd *cobra.Command, args []string) error { res, err := client.Run(args[0]) if err != nil { @@ -51,23 +57,18 @@ func newGetNotesCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { }, } - // Function providing dynamic auto-completion - completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { - if len(args) != 0 { - return nil, completion.BashCompDirectiveNoFileComp - } - return compListReleases(toComplete, cfg) - }) - f := cmd.Flags() f.IntVar(&client.Version, "revision", 0, "get the named release with revision") - flag := f.Lookup("revision") - completion.RegisterFlagCompletionFunc(flag, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + err := cmd.RegisterFlagCompletionFunc("revision", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if len(args) == 1 { return compListRevisions(cfg, args[0]) } - return nil, completion.BashCompDirectiveNoFileComp + return nil, cobra.ShellCompDirectiveNoFileComp }) + if err != nil { + log.Fatal(err) + } + return cmd } diff --git a/cmd/helm/get_values.go b/cmd/helm/get_values.go index a8c5acc5e..fa7b10fed 100644 --- a/cmd/helm/get_values.go +++ b/cmd/helm/get_values.go @@ -19,11 +19,11 @@ package main import ( "fmt" "io" + "log" "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/require" - "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/cli/output" ) @@ -46,6 +46,12 @@ func newGetValuesCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { Short: "download the values file for a named release", Long: getValuesHelp, Args: require.ExactArgs(1), + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) != 0 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + return compListReleases(toComplete, cfg) + }, RunE: func(cmd *cobra.Command, args []string) error { vals, err := client.Run(args[0]) if err != nil { @@ -55,23 +61,19 @@ func newGetValuesCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { }, } - // Function providing dynamic auto-completion - completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { - if len(args) != 0 { - return nil, completion.BashCompDirectiveNoFileComp - } - return compListReleases(toComplete, cfg) - }) - f := cmd.Flags() f.IntVar(&client.Version, "revision", 0, "get the named release with revision") - flag := f.Lookup("revision") - completion.RegisterFlagCompletionFunc(flag, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + err := cmd.RegisterFlagCompletionFunc("revision", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if len(args) == 1 { return compListRevisions(cfg, args[0]) } - return nil, completion.BashCompDirectiveNoFileComp + return nil, cobra.ShellCompDirectiveNoFileComp }) + + if err != nil { + log.Fatal(err) + } + f.BoolVarP(&client.AllValues, "all", "a", false, "dump all (computed) values") bindOutputFlag(cmd, &outfmt) diff --git a/cmd/helm/history.go b/cmd/helm/history.go index 3ef542e58..b49c52990 100644 --- a/cmd/helm/history.go +++ b/cmd/helm/history.go @@ -26,7 +26,6 @@ import ( "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/require" - "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/chart" "helm.sh/helm/v3/pkg/cli/output" @@ -61,6 +60,12 @@ func newHistoryCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { Short: "fetch release history", Aliases: []string{"hist"}, Args: require.ExactArgs(1), + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) != 0 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + return compListReleases(toComplete, cfg) + }, RunE: func(cmd *cobra.Command, args []string) error { history, err := getHistory(client, args[0]) if err != nil { @@ -71,14 +76,6 @@ func newHistoryCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { }, } - // Function providing dynamic auto-completion - completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { - if len(args) != 0 { - return nil, completion.BashCompDirectiveNoFileComp - } - return compListReleases(toComplete, cfg) - }) - f := cmd.Flags() f.IntVar(&client.Max, "max", 256, "maximum number of revision to include in history") bindOutputFlag(cmd, &outfmt) @@ -187,7 +184,7 @@ func min(x, y int) int { return y } -func compListRevisions(cfg *action.Configuration, releaseName string) ([]string, completion.BashCompDirective) { +func compListRevisions(cfg *action.Configuration, releaseName string) ([]string, cobra.ShellCompDirective) { client := action.NewHistory(cfg) var revisions []string @@ -195,7 +192,7 @@ func compListRevisions(cfg *action.Configuration, releaseName string) ([]string, for _, release := range hist { revisions = append(revisions, strconv.Itoa(release.Version)) } - return revisions, completion.BashCompDirectiveDefault + return revisions, cobra.ShellCompDirectiveDefault } - return nil, completion.BashCompDirectiveError + return nil, cobra.ShellCompDirectiveError } diff --git a/cmd/helm/install.go b/cmd/helm/install.go index 44f7336c0..b489c262d 100644 --- a/cmd/helm/install.go +++ b/cmd/helm/install.go @@ -26,7 +26,6 @@ import ( "github.com/spf13/pflag" "helm.sh/helm/v3/cmd/helm/require" - "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/chart" "helm.sh/helm/v3/pkg/chart/loader" @@ -114,6 +113,9 @@ func newInstallCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { Short: "install a chart", Long: installDesc, Args: require.MinimumNArgs(1), + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return compInstall(args, toComplete, client) + }, RunE: func(_ *cobra.Command, args []string) error { rel, err := runInstall(args, client, valueOpts, out) if err != nil { @@ -124,11 +126,6 @@ func newInstallCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { }, } - // Function providing dynamic auto-completion - completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { - return compInstall(args, toComplete, client) - }) - addInstallFlags(cmd.Flags(), client, valueOpts) bindOutputFlag(cmd, &outfmt) bindPostRenderFlag(cmd, &client.PostRenderer) @@ -242,7 +239,7 @@ func isChartInstallable(ch *chart.Chart) (bool, error) { } // Provide dynamic auto-completion for the install and template commands -func compInstall(args []string, toComplete string, client *action.Install) ([]string, completion.BashCompDirective) { +func compInstall(args []string, toComplete string, client *action.Install) ([]string, cobra.ShellCompDirective) { requiredArgs := 1 if client.GenerateName { requiredArgs = 0 @@ -250,5 +247,5 @@ func compInstall(args []string, toComplete string, client *action.Install) ([]st if len(args) == requiredArgs { return compListCharts(toComplete, true) } - return nil, completion.BashCompDirectiveNoFileComp + return nil, cobra.ShellCompDirectiveNoFileComp } diff --git a/cmd/helm/list.go b/cmd/helm/list.go index 08d6beb79..18e5ffe45 100644 --- a/cmd/helm/list.go +++ b/cmd/helm/list.go @@ -26,7 +26,6 @@ import ( "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/require" - "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/cli/output" "helm.sh/helm/v3/pkg/release" @@ -186,8 +185,8 @@ func (r *releaseListWriter) WriteYAML(out io.Writer) error { } // Provide dynamic auto-completion for release names -func compListReleases(toComplete string, cfg *action.Configuration) ([]string, completion.BashCompDirective) { - completion.CompDebugln(fmt.Sprintf("compListReleases with toComplete %s", toComplete)) +func compListReleases(toComplete string, cfg *action.Configuration) ([]string, cobra.ShellCompDirective) { + cobra.CompDebugln(fmt.Sprintf("compListReleases with toComplete %s", toComplete), settings.Debug) client := action.NewList(cfg) client.All = true @@ -197,7 +196,7 @@ func compListReleases(toComplete string, cfg *action.Configuration) ([]string, c client.SetStateMask() results, err := client.Run() if err != nil { - return nil, completion.BashCompDirectiveDefault + return nil, cobra.ShellCompDirectiveDefault } var choices []string @@ -205,5 +204,5 @@ func compListReleases(toComplete string, cfg *action.Configuration) ([]string, c choices = append(choices, res.Name) } - return choices, completion.BashCompDirectiveNoFileComp + return choices, cobra.ShellCompDirectiveNoFileComp } diff --git a/cmd/helm/load_plugins.go b/cmd/helm/load_plugins.go index 36de50135..e439c8407 100644 --- a/cmd/helm/load_plugins.go +++ b/cmd/helm/load_plugins.go @@ -32,7 +32,6 @@ import ( "github.com/spf13/cobra" "sigs.k8s.io/yaml" - "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/plugin" ) @@ -97,6 +96,7 @@ func loadPlugins(baseCmd *cobra.Command, out io.Writer) { // This passes all the flags to the subcommand. DisableFlagParsing: true, } + // TODO: Make sure a command with this name does not already exist. baseCmd.AddCommand(c) @@ -105,7 +105,7 @@ func loadPlugins(baseCmd *cobra.Command, out io.Writer) { // We only do this when necessary (for the "completion" and "__complete" commands) to avoid the // risk of a rogue plugin affecting Helm's normal behavior. subCmd, _, err := baseCmd.Find(os.Args[1:]) - if (err == nil && (subCmd.Name() == "completion" || subCmd.Name() == completion.CompRequestCmd)) || + if (err == nil && (subCmd.Name() == "completion" || subCmd.Name() == cobra.ShellCompRequestCmd)) || /* for the tests */ subCmd == baseCmd.Root() { loadCompletionForPlugin(c, plug) } @@ -247,9 +247,9 @@ func addPluginCommands(plugin *plugin.Plugin, baseCmd *cobra.Command, cmds *plug // Only setup dynamic completion if there are no sub-commands. This avoids // calling plugin.complete at every completion, which greatly simplifies // development of plugin.complete for plugin developers. - completion.RegisterValidArgsFunc(baseCmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + baseCmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { return pluginDynamicComp(plugin, cmd, args, toComplete) - }) + } } // Create fake flags. @@ -322,12 +322,12 @@ func loadFile(path string) (*pluginCommand, error) { // pluginDynamicComp call the plugin.complete script of the plugin (if available) // to obtain the dynamic completion choices. It must pass all the flags and sub-commands // specified in the command-line to the plugin.complete executable (except helm's global flags) -func pluginDynamicComp(plug *plugin.Plugin, cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { +func pluginDynamicComp(plug *plugin.Plugin, cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { md := plug.Metadata u, err := processParent(cmd, args) if err != nil { - return nil, completion.BashCompDirectiveError + return nil, cobra.ShellCompDirectiveError } // We will call the dynamic completion script of the plugin @@ -343,12 +343,12 @@ func pluginDynamicComp(plug *plugin.Plugin, cmd *cobra.Command, args []string, t } plugin.SetupPluginEnv(settings, md.Name, plug.Dir) - completion.CompDebugln(fmt.Sprintf("calling %s with args %v", main, argv)) + cobra.CompDebugln(fmt.Sprintf("calling %s with args %v", main, argv), settings.Debug) buf := new(bytes.Buffer) if err := callPluginExecutable(md.Name, main, argv, buf); err != nil { // The dynamic completion file is optional for a plugin, so this error is ok. - completion.CompDebugln(fmt.Sprintf("Unable to call %s: %v", main, err.Error())) - return nil, completion.BashCompDirectiveDefault + cobra.CompDebugln(fmt.Sprintf("Unable to call %s: %v", main, err.Error()), settings.Debug) + return nil, cobra.ShellCompDirectiveDefault } var completions []string @@ -361,12 +361,12 @@ func pluginDynamicComp(plug *plugin.Plugin, cmd *cobra.Command, args []string, t // Check if the last line of output is of the form :, which // indicates the BashCompletionDirective. - directive := completion.BashCompDirectiveDefault + directive := cobra.ShellCompDirectiveDefault if len(completions) > 0 { lastLine := completions[len(completions)-1] if len(lastLine) > 1 && lastLine[0] == ':' { if strInt, err := strconv.Atoi(lastLine[1:]); err == nil { - directive = completion.BashCompDirective(strInt) + directive = cobra.ShellCompDirective(strInt) completions = completions[:len(completions)-1] } } diff --git a/cmd/helm/plugin_uninstall.go b/cmd/helm/plugin_uninstall.go index 66cdaccdc..b2290fb9b 100644 --- a/cmd/helm/plugin_uninstall.go +++ b/cmd/helm/plugin_uninstall.go @@ -24,7 +24,6 @@ import ( "github.com/pkg/errors" "github.com/spf13/cobra" - "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/plugin" ) @@ -39,6 +38,12 @@ func newPluginUninstallCmd(out io.Writer) *cobra.Command { Use: "uninstall ...", Aliases: []string{"rm", "remove"}, Short: "uninstall one or more Helm plugins", + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) != 0 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + return compListPlugins(toComplete), cobra.ShellCompDirectiveNoFileComp + }, PreRunE: func(cmd *cobra.Command, args []string) error { return o.complete(args) }, @@ -46,15 +51,6 @@ func newPluginUninstallCmd(out io.Writer) *cobra.Command { return o.run(out) }, } - - // Function providing dynamic auto-completion - completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { - if len(args) != 0 { - return nil, completion.BashCompDirectiveNoFileComp - } - return compListPlugins(toComplete), completion.BashCompDirectiveNoFileComp - }) - return cmd } diff --git a/cmd/helm/plugin_update.go b/cmd/helm/plugin_update.go index 23f840b4a..c46444e0d 100644 --- a/cmd/helm/plugin_update.go +++ b/cmd/helm/plugin_update.go @@ -24,7 +24,6 @@ import ( "github.com/pkg/errors" "github.com/spf13/cobra" - "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/plugin" "helm.sh/helm/v3/pkg/plugin/installer" ) @@ -40,6 +39,12 @@ func newPluginUpdateCmd(out io.Writer) *cobra.Command { Use: "update ...", Aliases: []string{"up"}, Short: "update one or more Helm plugins", + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) != 0 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + return compListPlugins(toComplete), cobra.ShellCompDirectiveNoFileComp + }, PreRunE: func(cmd *cobra.Command, args []string) error { return o.complete(args) }, @@ -47,15 +52,6 @@ func newPluginUpdateCmd(out io.Writer) *cobra.Command { return o.run(out) }, } - - // Function providing dynamic auto-completion - completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { - if len(args) != 0 { - return nil, completion.BashCompDirectiveNoFileComp - } - return compListPlugins(toComplete), completion.BashCompDirectiveNoFileComp - }) - return cmd } diff --git a/cmd/helm/pull.go b/cmd/helm/pull.go index 16cd10467..d10c629db 100644 --- a/cmd/helm/pull.go +++ b/cmd/helm/pull.go @@ -23,7 +23,6 @@ import ( "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/require" - "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/action" ) @@ -51,6 +50,12 @@ func newPullCmd(out io.Writer) *cobra.Command { Aliases: []string{"fetch"}, Long: pullDesc, Args: require.MinimumNArgs(1), + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) != 0 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + return compListCharts(toComplete, false) + }, RunE: func(cmd *cobra.Command, args []string) error { client.Settings = settings if client.Version == "" && client.Devel { @@ -69,14 +74,6 @@ func newPullCmd(out io.Writer) *cobra.Command { }, } - // Function providing dynamic auto-completion - completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { - if len(args) != 0 { - return nil, completion.BashCompDirectiveNoFileComp - } - return compListCharts(toComplete, false) - }) - f := cmd.Flags() f.BoolVar(&client.Devel, "devel", false, "use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored.") f.BoolVar(&client.Untar, "untar", false, "if set to true, will untar the chart after downloading it") diff --git a/cmd/helm/release_testing.go b/cmd/helm/release_testing.go index 036d96794..37cac6186 100644 --- a/cmd/helm/release_testing.go +++ b/cmd/helm/release_testing.go @@ -24,7 +24,6 @@ import ( "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/require" - "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/cli/output" ) @@ -46,6 +45,12 @@ func newReleaseTestCmd(cfg *action.Configuration, out io.Writer) *cobra.Command Short: "run tests for a release", Long: releaseTestHelp, Args: require.ExactArgs(1), + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) != 0 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + return compListReleases(toComplete, cfg) + }, RunE: func(cmd *cobra.Command, args []string) error { client.Namespace = settings.Namespace() rel, runErr := client.Run(args[0]) @@ -72,14 +77,6 @@ func newReleaseTestCmd(cfg *action.Configuration, out io.Writer) *cobra.Command }, } - // Function providing dynamic auto-completion - completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { - if len(args) != 0 { - return nil, completion.BashCompDirectiveNoFileComp - } - return compListReleases(toComplete, cfg) - }) - f := cmd.Flags() f.DurationVar(&client.Timeout, "timeout", 300*time.Second, "time to wait for any individual Kubernetes operation (like Jobs for hooks)") f.BoolVar(&outputLogs, "logs", false, "dump the logs from test pods (this runs after all tests are complete, but before any cleanup)") diff --git a/cmd/helm/repo_remove.go b/cmd/helm/repo_remove.go index 5dad4e5e0..e6e9cb681 100644 --- a/cmd/helm/repo_remove.go +++ b/cmd/helm/repo_remove.go @@ -26,7 +26,6 @@ import ( "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/require" - "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/helmpath" "helm.sh/helm/v3/pkg/repo" ) @@ -45,6 +44,9 @@ func newRepoRemoveCmd(out io.Writer) *cobra.Command { Aliases: []string{"rm"}, Short: "remove one or more chart repositories", Args: require.MinimumNArgs(1), + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return compListRepos(toComplete, args), cobra.ShellCompDirectiveNoFileComp + }, RunE: func(cmd *cobra.Command, args []string) error { o.repoFile = settings.RepositoryConfig o.repoCache = settings.RepositoryCache @@ -52,12 +54,6 @@ func newRepoRemoveCmd(out io.Writer) *cobra.Command { return o.run(out) }, } - - // Function providing dynamic auto-completion - completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { - return compListRepos(toComplete, args), completion.BashCompDirectiveNoFileComp - }) - return cmd } diff --git a/cmd/helm/rollback.go b/cmd/helm/rollback.go index 745e910b2..3b336d0ff 100644 --- a/cmd/helm/rollback.go +++ b/cmd/helm/rollback.go @@ -25,7 +25,6 @@ import ( "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/require" - "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/action" ) @@ -47,6 +46,12 @@ func newRollbackCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { Short: "roll back a release to a previous revision", Long: rollbackDesc, Args: require.MinimumNArgs(1), + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) != 0 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + return compListReleases(toComplete, cfg) + }, RunE: func(cmd *cobra.Command, args []string) error { if len(args) > 1 { ver, err := strconv.Atoi(args[1]) @@ -65,14 +70,6 @@ func newRollbackCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { }, } - // Function providing dynamic auto-completion - completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { - if len(args) != 0 { - return nil, completion.BashCompDirectiveNoFileComp - } - return compListReleases(toComplete, cfg) - }) - f := cmd.Flags() f.BoolVar(&client.DryRun, "dry-run", false, "simulate a rollback") f.BoolVar(&client.Recreate, "recreate-pods", false, "performs pods restart for the resource if applicable") diff --git a/cmd/helm/root.go b/cmd/helm/root.go index 143745f29..69f5855d9 100644 --- a/cmd/helm/root.go +++ b/cmd/helm/root.go @@ -20,6 +20,7 @@ import ( "context" "fmt" "io" + "log" "strings" "github.com/spf13/cobra" @@ -27,7 +28,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/tools/clientcmd" - "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/internal/experimental/registry" "helm.sh/helm/v3/pkg/action" ) @@ -70,24 +70,22 @@ By default, the default directories depend on the Operating System. The defaults func newRootCmd(actionConfig *action.Configuration, out io.Writer, args []string) *cobra.Command { cmd := &cobra.Command{ - Use: "helm", - Short: "The Helm package manager for Kubernetes.", - Long: globalUsage, - SilenceUsage: true, - BashCompletionFunction: completion.GetBashCustomFunction(), + Use: "helm", + Short: "The Helm package manager for Kubernetes.", + Long: globalUsage, + SilenceUsage: true, } flags := cmd.PersistentFlags() settings.AddFlags(flags) // Setup shell completion for the namespace flag - flag := flags.Lookup("namespace") - completion.RegisterFlagCompletionFunc(flag, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + err := cmd.RegisterFlagCompletionFunc("namespace", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if client, err := actionConfig.KubernetesClientSet(); err == nil { // Choose a long enough timeout that the user notices somethings is not working // but short enough that the user is not made to wait very long to := int64(3) - completion.CompDebugln(fmt.Sprintf("About to call kube client for namespaces with timeout of: %d", to)) + cobra.CompDebugln(fmt.Sprintf("About to call kube client for namespaces with timeout of: %d", to), settings.Debug) nsNames := []string{} if namespaces, err := client.CoreV1().Namespaces().List(context.Background(), metav1.ListOptions{TimeoutSeconds: &to}); err == nil { @@ -96,16 +94,19 @@ func newRootCmd(actionConfig *action.Configuration, out io.Writer, args []string nsNames = append(nsNames, ns.Name) } } - return nsNames, completion.BashCompDirectiveNoFileComp + return nsNames, cobra.ShellCompDirectiveNoFileComp } } - return nil, completion.BashCompDirectiveDefault + return nil, cobra.ShellCompDirectiveDefault }) + if err != nil { + log.Fatal(err) + } + // Setup shell completion for the kube-context flag - flag = flags.Lookup("kube-context") - completion.RegisterFlagCompletionFunc(flag, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { - completion.CompDebugln("About to get the different kube-contexts") + err = cmd.RegisterFlagCompletionFunc("kube-context", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + cobra.CompDebugln("About to get the different kube-contexts", settings.Debug) loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() if len(settings.KubeConfig) > 0 { @@ -120,11 +121,15 @@ func newRootCmd(actionConfig *action.Configuration, out io.Writer, args []string ctxs = append(ctxs, name) } } - return ctxs, completion.BashCompDirectiveNoFileComp + return ctxs, cobra.ShellCompDirectiveNoFileComp } - return nil, completion.BashCompDirectiveNoFileComp + return nil, cobra.ShellCompDirectiveNoFileComp }) + if err != nil { + log.Fatal(err) + } + // We can safely ignore any errors that flags.Parse encounters since // those errors will be caught later during the call to cmd.Execution. // This call is required to gather configuration information prior to @@ -164,9 +169,6 @@ func newRootCmd(actionConfig *action.Configuration, out io.Writer, args []string // Hidden documentation generator command: 'helm docs' newDocsCmd(out), - - // Setup the special hidden __complete command to allow for dynamic auto-completion - completion.NewCompleteCmd(settings, out), ) // Add *experimental* subcommands diff --git a/cmd/helm/search_repo.go b/cmd/helm/search_repo.go index c7f0da974..dd530379b 100644 --- a/cmd/helm/search_repo.go +++ b/cmd/helm/search_repo.go @@ -32,7 +32,6 @@ import ( "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/search" - "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/cli/output" "helm.sh/helm/v3/pkg/helmpath" "helm.sh/helm/v3/pkg/repo" @@ -290,8 +289,8 @@ func compListChartsOfRepo(repoName string, prefix string) []string { // Provide dynamic auto-completion for commands that operate on charts (e.g., helm show) // When true, the includeFiles argument indicates that completion should include local files (e.g., local charts) -func compListCharts(toComplete string, includeFiles bool) ([]string, completion.BashCompDirective) { - completion.CompDebugln(fmt.Sprintf("compListCharts with toComplete %s", toComplete)) +func compListCharts(toComplete string, includeFiles bool) ([]string, cobra.ShellCompDirective) { + cobra.CompDebugln(fmt.Sprintf("compListCharts with toComplete %s", toComplete), settings.Debug) noSpace := false noFile := false @@ -312,7 +311,7 @@ func compListCharts(toComplete string, includeFiles bool) ([]string, completion. noSpace = true } } - completion.CompDebugln(fmt.Sprintf("Completions after repos: %v", completions)) + cobra.CompDebugln(fmt.Sprintf("Completions after repos: %v", completions), settings.Debug) // Now handle completions for url prefixes for _, url := range []string{"https://", "http://", "file://"} { @@ -328,7 +327,7 @@ func compListCharts(toComplete string, includeFiles bool) ([]string, completion. noSpace = true } } - completion.CompDebugln(fmt.Sprintf("Completions after urls: %v", completions)) + cobra.CompDebugln(fmt.Sprintf("Completions after urls: %v", completions), settings.Debug) // Finally, provide file completion if we need to. // We only do this if: @@ -347,22 +346,22 @@ func compListCharts(toComplete string, includeFiles bool) ([]string, completion. } } } - completion.CompDebugln(fmt.Sprintf("Completions after files: %v", completions)) + cobra.CompDebugln(fmt.Sprintf("Completions after files: %v", completions), settings.Debug) // If the user didn't provide any input to completion, // we provide a hint that a path can also be used if includeFiles && len(toComplete) == 0 { completions = append(completions, "./", "/") } - completion.CompDebugln(fmt.Sprintf("Completions after checking empty input: %v", completions)) + cobra.CompDebugln(fmt.Sprintf("Completions after checking empty input: %v", completions), settings.Debug) - directive := completion.BashCompDirectiveDefault + directive := cobra.ShellCompDirectiveDefault if noFile { - directive = directive | completion.BashCompDirectiveNoFileComp + directive = directive | cobra.ShellCompDirectiveNoFileComp } if noSpace { - directive = directive | completion.BashCompDirectiveNoSpace - // The completion.BashCompDirective flags do not work for zsh right now. + directive = directive | cobra.ShellCompDirectiveNoSpace + // The cobra.ShellCompDirective flags do not work for zsh right now. // We handle it ourselves instead. completions = compEnforceNoSpace(completions) } @@ -380,7 +379,7 @@ func compEnforceNoSpace(completions []string) []string { // We only do this if there is a single choice for completion. if len(completions) == 1 { completions = append(completions, completions[0]+".") - completion.CompDebugln(fmt.Sprintf("compEnforceNoSpace: completions now are %v", completions)) + cobra.CompDebugln(fmt.Sprintf("compEnforceNoSpace: completions now are %v", completions), settings.Debug) } return completions } diff --git a/cmd/helm/show.go b/cmd/helm/show.go index 91c35a53c..c78069a09 100644 --- a/cmd/helm/show.go +++ b/cmd/helm/show.go @@ -23,7 +23,6 @@ import ( "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/require" - "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/action" ) @@ -63,18 +62,19 @@ func newShowCmd(out io.Writer) *cobra.Command { } // Function providing dynamic auto-completion - validArgsFunc := func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + validArgsFunc := func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if len(args) != 0 { - return nil, completion.BashCompDirectiveNoFileComp + return nil, cobra.ShellCompDirectiveNoFileComp } return compListCharts(toComplete, true) } all := &cobra.Command{ - Use: "all [CHART]", - Short: "show all information of the chart", - Long: showAllDesc, - Args: require.ExactArgs(1), + Use: "all [CHART]", + Short: "show all information of the chart", + Long: showAllDesc, + Args: require.ExactArgs(1), + ValidArgsFunction: validArgsFunc, RunE: func(cmd *cobra.Command, args []string) error { client.OutputFormat = action.ShowAll output, err := runShow(args, client) @@ -87,10 +87,11 @@ func newShowCmd(out io.Writer) *cobra.Command { } valuesSubCmd := &cobra.Command{ - Use: "values [CHART]", - Short: "show the chart's values", - Long: showValuesDesc, - Args: require.ExactArgs(1), + Use: "values [CHART]", + Short: "show the chart's values", + Long: showValuesDesc, + Args: require.ExactArgs(1), + ValidArgsFunction: validArgsFunc, RunE: func(cmd *cobra.Command, args []string) error { client.OutputFormat = action.ShowValues output, err := runShow(args, client) @@ -103,10 +104,11 @@ func newShowCmd(out io.Writer) *cobra.Command { } chartSubCmd := &cobra.Command{ - Use: "chart [CHART]", - Short: "show the chart's definition", - Long: showChartDesc, - Args: require.ExactArgs(1), + Use: "chart [CHART]", + Short: "show the chart's definition", + Long: showChartDesc, + Args: require.ExactArgs(1), + ValidArgsFunction: validArgsFunc, RunE: func(cmd *cobra.Command, args []string) error { client.OutputFormat = action.ShowChart output, err := runShow(args, client) @@ -119,10 +121,11 @@ func newShowCmd(out io.Writer) *cobra.Command { } readmeSubCmd := &cobra.Command{ - Use: "readme [CHART]", - Short: "show the chart's README", - Long: readmeChartDesc, - Args: require.ExactArgs(1), + Use: "readme [CHART]", + Short: "show the chart's README", + Long: readmeChartDesc, + Args: require.ExactArgs(1), + ValidArgsFunction: validArgsFunc, RunE: func(cmd *cobra.Command, args []string) error { client.OutputFormat = action.ShowReadme output, err := runShow(args, client) @@ -138,9 +141,6 @@ func newShowCmd(out io.Writer) *cobra.Command { for _, subCmd := range cmds { addShowFlags(subCmd, client) showCommand.AddCommand(subCmd) - - // Register the completion function for each subcommand - completion.RegisterValidArgsFunc(subCmd, validArgsFunc) } return showCommand diff --git a/cmd/helm/status.go b/cmd/helm/status.go index 2efb2006c..5913d08df 100644 --- a/cmd/helm/status.go +++ b/cmd/helm/status.go @@ -19,13 +19,13 @@ package main import ( "fmt" "io" + "log" "strings" "time" "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/require" - "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/chartutil" "helm.sh/helm/v3/pkg/cli/output" @@ -53,6 +53,12 @@ func newStatusCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { Short: "display the status of the named release", Long: statusHelp, Args: require.ExactArgs(1), + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) != 0 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + return compListReleases(toComplete, cfg) + }, RunE: func(cmd *cobra.Command, args []string) error { rel, err := client.Run(args[0]) if err != nil { @@ -66,25 +72,21 @@ func newStatusCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { }, } - // Function providing dynamic auto-completion - completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { - if len(args) != 0 { - return nil, completion.BashCompDirectiveNoFileComp - } - return compListReleases(toComplete, cfg) - }) - f := cmd.Flags() f.IntVar(&client.Version, "revision", 0, "if set, display the status of the named release with revision") - flag := f.Lookup("revision") - completion.RegisterFlagCompletionFunc(flag, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { + + err := cmd.RegisterFlagCompletionFunc("revision", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if len(args) == 1 { return compListRevisions(cfg, args[0]) } - return nil, completion.BashCompDirectiveNoFileComp + return nil, cobra.ShellCompDirectiveNoFileComp }) + if err != nil { + log.Fatal(err) + } + bindOutputFlag(cmd, &outfmt) return cmd diff --git a/cmd/helm/template.go b/cmd/helm/template.go index a4438b50c..0fc29e189 100644 --- a/cmd/helm/template.go +++ b/cmd/helm/template.go @@ -28,7 +28,6 @@ import ( "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/require" - "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/chartutil" "helm.sh/helm/v3/pkg/cli/values" @@ -56,6 +55,9 @@ func newTemplateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { Short: "locally render templates", Long: templateDesc, Args: require.MinimumNArgs(1), + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return compInstall(args, toComplete, client) + }, RunE: func(_ *cobra.Command, args []string) error { client.DryRun = true client.ReleaseName = "RELEASE-NAME" @@ -136,11 +138,6 @@ func newTemplateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { }, } - // Function providing dynamic auto-completion - completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { - return compInstall(args, toComplete, client) - }) - f := cmd.Flags() addInstallFlags(f, client, valueOpts) f.StringArrayVarP(&showFiles, "show-only", "s", []string{}, "only show manifests rendered from the given templates") diff --git a/cmd/helm/testdata/output/output-comp.txt b/cmd/helm/testdata/output/output-comp.txt index de5f16f1d..be574756b 100644 --- a/cmd/helm/testdata/output/output-comp.txt +++ b/cmd/helm/testdata/output/output-comp.txt @@ -2,3 +2,4 @@ table json yaml :0 +Completion ended with directive: ShellCompDirectiveDefault diff --git a/cmd/helm/testdata/output/plugin_args_comp.txt b/cmd/helm/testdata/output/plugin_args_comp.txt index 8fb01cc23..007112d31 100644 --- a/cmd/helm/testdata/output/plugin_args_comp.txt +++ b/cmd/helm/testdata/output/plugin_args_comp.txt @@ -3,3 +3,4 @@ Namespace: default Num args received: 1 Args received: :4 +Completion ended with directive: ShellCompDirectiveNoFileComp diff --git a/cmd/helm/testdata/output/plugin_args_flag_comp.txt b/cmd/helm/testdata/output/plugin_args_flag_comp.txt index 92f0e58a8..c7a09e3fa 100644 --- a/cmd/helm/testdata/output/plugin_args_flag_comp.txt +++ b/cmd/helm/testdata/output/plugin_args_flag_comp.txt @@ -3,3 +3,4 @@ Namespace: default Num args received: 2 Args received: --myflag :4 +Completion ended with directive: ShellCompDirectiveNoFileComp diff --git a/cmd/helm/testdata/output/plugin_args_many_args_comp.txt b/cmd/helm/testdata/output/plugin_args_many_args_comp.txt index 86fa768bb..f3c386b6d 100644 --- a/cmd/helm/testdata/output/plugin_args_many_args_comp.txt +++ b/cmd/helm/testdata/output/plugin_args_many_args_comp.txt @@ -3,3 +3,4 @@ Namespace: mynamespace Num args received: 2 Args received: --myflag start :2 +Completion ended with directive: ShellCompDirectiveNoSpace diff --git a/cmd/helm/testdata/output/plugin_args_ns_comp.txt b/cmd/helm/testdata/output/plugin_args_ns_comp.txt index e12867daa..26cd79b98 100644 --- a/cmd/helm/testdata/output/plugin_args_ns_comp.txt +++ b/cmd/helm/testdata/output/plugin_args_ns_comp.txt @@ -3,3 +3,4 @@ Namespace: mynamespace Num args received: 1 Args received: :2 +Completion ended with directive: ShellCompDirectiveNoSpace diff --git a/cmd/helm/testdata/output/plugin_echo_bad_directive.txt b/cmd/helm/testdata/output/plugin_echo_bad_directive.txt index f4b86cd47..8038b9525 100644 --- a/cmd/helm/testdata/output/plugin_echo_bad_directive.txt +++ b/cmd/helm/testdata/output/plugin_echo_bad_directive.txt @@ -3,3 +3,4 @@ Namespace: default Num args received: 1 Args received: :0 +Completion ended with directive: ShellCompDirectiveDefault diff --git a/cmd/helm/testdata/output/plugin_echo_no_directive.txt b/cmd/helm/testdata/output/plugin_echo_no_directive.txt index 6266dd4d9..7001be0e9 100644 --- a/cmd/helm/testdata/output/plugin_echo_no_directive.txt +++ b/cmd/helm/testdata/output/plugin_echo_no_directive.txt @@ -3,3 +3,4 @@ Namespace: mynamespace Num args received: 1 Args received: :0 +Completion ended with directive: ShellCompDirectiveDefault diff --git a/cmd/helm/testdata/output/revision-comp.txt b/cmd/helm/testdata/output/revision-comp.txt index b4799f059..d06947d9d 100644 --- a/cmd/helm/testdata/output/revision-comp.txt +++ b/cmd/helm/testdata/output/revision-comp.txt @@ -3,3 +3,4 @@ 10 11 :0 +Completion ended with directive: ShellCompDirectiveDefault diff --git a/cmd/helm/testdata/output/revision-wrong-args-comp.txt b/cmd/helm/testdata/output/revision-wrong-args-comp.txt index b6f867176..8d9fad576 100644 --- a/cmd/helm/testdata/output/revision-wrong-args-comp.txt +++ b/cmd/helm/testdata/output/revision-wrong-args-comp.txt @@ -1 +1,2 @@ :4 +Completion ended with directive: ShellCompDirectiveNoFileComp diff --git a/cmd/helm/testdata/output/status-comp.txt b/cmd/helm/testdata/output/status-comp.txt index c97882964..8d4d21df7 100644 --- a/cmd/helm/testdata/output/status-comp.txt +++ b/cmd/helm/testdata/output/status-comp.txt @@ -1,3 +1,4 @@ aramis athos :4 +Completion ended with directive: ShellCompDirectiveNoFileComp diff --git a/cmd/helm/testdata/output/status-wrong-args-comp.txt b/cmd/helm/testdata/output/status-wrong-args-comp.txt index b6f867176..8d9fad576 100644 --- a/cmd/helm/testdata/output/status-wrong-args-comp.txt +++ b/cmd/helm/testdata/output/status-wrong-args-comp.txt @@ -1 +1,2 @@ :4 +Completion ended with directive: ShellCompDirectiveNoFileComp diff --git a/cmd/helm/uninstall.go b/cmd/helm/uninstall.go index 85fa822bd..509918e53 100644 --- a/cmd/helm/uninstall.go +++ b/cmd/helm/uninstall.go @@ -24,7 +24,6 @@ import ( "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/require" - "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/action" ) @@ -48,6 +47,12 @@ func newUninstallCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { Short: "uninstall a release", Long: uninstallDesc, Args: require.MinimumNArgs(1), + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) != 0 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + return compListReleases(toComplete, cfg) + }, RunE: func(cmd *cobra.Command, args []string) error { for i := 0; i < len(args); i++ { @@ -65,14 +70,6 @@ func newUninstallCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { }, } - // Function providing dynamic auto-completion - completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { - if len(args) != 0 { - return nil, completion.BashCompDirectiveNoFileComp - } - return compListReleases(toComplete, cfg) - }) - f := cmd.Flags() f.BoolVar(&client.DryRun, "dry-run", false, "simulate a uninstall") f.BoolVar(&client.DisableHooks, "no-hooks", false, "prevent hooks from running during uninstallation") diff --git a/cmd/helm/upgrade.go b/cmd/helm/upgrade.go index f8103b485..1db899eae 100644 --- a/cmd/helm/upgrade.go +++ b/cmd/helm/upgrade.go @@ -25,7 +25,6 @@ import ( "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/require" - "helm.sh/helm/v3/internal/completion" "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/chart/loader" "helm.sh/helm/v3/pkg/cli/output" @@ -72,6 +71,15 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { Short: "upgrade a release", Long: upgradeDesc, Args: require.ExactArgs(2), + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return compListReleases(toComplete, cfg) + } + if len(args) == 1 { + return compListCharts(toComplete, true) + } + return nil, cobra.ShellCompDirectiveNoFileComp + }, RunE: func(cmd *cobra.Command, args []string) error { client.Namespace = settings.Namespace() @@ -155,17 +163,6 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { }, } - // Function providing dynamic auto-completion - completion.RegisterValidArgsFunc(cmd, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { - if len(args) == 0 { - return compListReleases(toComplete, cfg) - } - if len(args) == 1 { - return compListCharts(toComplete, true) - } - return nil, completion.BashCompDirectiveNoFileComp - }) - f := cmd.Flags() f.BoolVar(&createNamespace, "create-namespace", false, "if --install is set, create the release namespace if not present") f.BoolVarP(&client.Install, "install", "i", false, "if a release by this name doesn't already exist, run an install") diff --git a/internal/completion/complete.go b/internal/completion/complete.go deleted file mode 100644 index 545f5b0dd..000000000 --- a/internal/completion/complete.go +++ /dev/null @@ -1,399 +0,0 @@ -/* -Copyright The Helm Authors. -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package completion - -import ( - "errors" - "fmt" - "io" - "log" - "os" - "strings" - - "github.com/spf13/cobra" - "github.com/spf13/pflag" - - "helm.sh/helm/v3/cmd/helm/require" - "helm.sh/helm/v3/pkg/cli" -) - -// ================================================================================== -// The below code supports dynamic shell completion in Go. -// This should ultimately be pushed down into Cobra. -// ================================================================================== - -// CompRequestCmd Hidden command to request completion results from the program. -// Used by the shell completion script. -const CompRequestCmd = "__complete" - -// Global map allowing to find completion functions for commands or flags. -var validArgsFunctions = map[interface{}]func(cmd *cobra.Command, args []string, toComplete string) ([]string, BashCompDirective){} - -// BashCompDirective is a bit map representing the different behaviors the shell -// can be instructed to have once completions have been provided. -type BashCompDirective int - -const ( - // BashCompDirectiveError indicates an error occurred and completions should be ignored. - BashCompDirectiveError BashCompDirective = 1 << iota - - // BashCompDirectiveNoSpace indicates that the shell should not add a space - // after the completion even if there is a single completion provided. - BashCompDirectiveNoSpace - - // BashCompDirectiveNoFileComp indicates that the shell should not provide - // file completion even when no completion is provided. - // This currently does not work for zsh or bash < 4 - BashCompDirectiveNoFileComp - - // BashCompDirectiveDefault indicates to let the shell perform its default - // behavior after completions have been provided. - BashCompDirectiveDefault BashCompDirective = 0 -) - -// GetBashCustomFunction returns the bash code to handle custom go completion -// This should eventually be provided by Cobra -func GetBashCustomFunction() string { - return fmt.Sprintf(` -__helm_custom_func() -{ - __helm_debug "${FUNCNAME[0]}: c is $c, words[@] is ${words[@]}, #words[@] is ${#words[@]}" - __helm_debug "${FUNCNAME[0]}: cur is ${cur}, cword is ${cword}, words is ${words}" - - local out requestComp lastParam lastChar - requestComp="${words[0]} %[1]s ${words[@]:1}" - - lastParam=${words[$((${#words[@]}-1))]} - lastChar=${lastParam:$((${#lastParam}-1)):1} - __helm_debug "${FUNCNAME[0]}: lastParam ${lastParam}, lastChar ${lastChar}" - - if [ -z "${cur}" ] && [ "${lastChar}" != "=" ]; then - # If the last parameter is complete (there is a space following it) - # We add an extra empty parameter so we can indicate this to the go method. - __helm_debug "${FUNCNAME[0]}: Adding extra empty parameter" - requestComp="${requestComp} \"\"" - fi - - __helm_debug "${FUNCNAME[0]}: calling ${requestComp}" - # Use eval to handle any environment variables and such - out=$(eval ${requestComp} 2>/dev/null) - - # Extract the directive int at the very end of the output following a : - directive=${out##*:} - # Remove the directive - out=${out%%:*} - if [ "${directive}" = "${out}" ]; then - # There is not directive specified - directive=0 - fi - __helm_debug "${FUNCNAME[0]}: the completion directive is: ${directive}" - __helm_debug "${FUNCNAME[0]}: the completions are: ${out[*]}" - - if [ $((${directive} & %[2]d)) -ne 0 ]; then - __helm_debug "${FUNCNAME[0]}: received error, completion failed" - else - if [ $((${directive} & %[3]d)) -ne 0 ]; then - if [[ $(type -t compopt) = "builtin" ]]; then - __helm_debug "${FUNCNAME[0]}: activating no space" - compopt -o nospace - fi - fi - if [ $((${directive} & %[4]d)) -ne 0 ]; then - if [[ $(type -t compopt) = "builtin" ]]; then - __helm_debug "${FUNCNAME[0]}: activating no file completion" - compopt +o default - fi - fi - - while IFS='' read -r comp; do - COMPREPLY+=("$comp") - done < <(compgen -W "${out[*]}" -- "$cur") - fi -} -`, CompRequestCmd, BashCompDirectiveError, BashCompDirectiveNoSpace, BashCompDirectiveNoFileComp) -} - -// RegisterValidArgsFunc should be called to register a function to provide argument completion for a command -func RegisterValidArgsFunc(cmd *cobra.Command, f func(cmd *cobra.Command, args []string, toComplete string) ([]string, BashCompDirective)) { - if _, exists := validArgsFunctions[cmd]; exists { - log.Fatal(fmt.Sprintf("RegisterValidArgsFunc: command '%s' already registered", cmd.Name())) - } - validArgsFunctions[cmd] = f -} - -// RegisterFlagCompletionFunc should be called to register a function to provide completion for a flag -func RegisterFlagCompletionFunc(flag *pflag.Flag, f func(cmd *cobra.Command, args []string, toComplete string) ([]string, BashCompDirective)) { - if _, exists := validArgsFunctions[flag]; exists { - log.Fatal(fmt.Sprintf("RegisterFlagCompletionFunc: flag '%s' already registered", flag.Name)) - } - validArgsFunctions[flag] = f - - // Make sure the completion script call the __helm_custom_func for the registered flag. - // This is essential to make the = form work. E.g., helm -n= or helm status --output= - if flag.Annotations == nil { - flag.Annotations = map[string][]string{} - } - flag.Annotations[cobra.BashCompCustom] = []string{"__helm_custom_func"} -} - -var debug = true - -// Returns a string listing the different directive enabled in the specified parameter -func (d BashCompDirective) string() string { - var directives []string - if d&BashCompDirectiveError != 0 { - directives = append(directives, "BashCompDirectiveError") - } - if d&BashCompDirectiveNoSpace != 0 { - directives = append(directives, "BashCompDirectiveNoSpace") - } - if d&BashCompDirectiveNoFileComp != 0 { - directives = append(directives, "BashCompDirectiveNoFileComp") - } - if len(directives) == 0 { - directives = append(directives, "BashCompDirectiveDefault") - } - - if d > BashCompDirectiveError+BashCompDirectiveNoSpace+BashCompDirectiveNoFileComp { - return fmt.Sprintf("ERROR: unexpected BashCompDirective value: %d", d) - } - return strings.Join(directives, ", ") -} - -// NewCompleteCmd add a special hidden command that an be used to request completions -func NewCompleteCmd(settings *cli.EnvSettings, out io.Writer) *cobra.Command { - debug = settings.Debug - return &cobra.Command{ - Use: fmt.Sprintf("%s [command-line]", CompRequestCmd), - DisableFlagsInUseLine: true, - Hidden: true, - DisableFlagParsing: true, - Args: require.MinimumNArgs(1), - Short: "Request shell completion choices for the specified command-line", - Long: fmt.Sprintf("%s is a special command that is used by the shell completion logic\n%s", - CompRequestCmd, "to request completion choices for the specified command-line."), - Run: func(cmd *cobra.Command, args []string) { - CompDebugln(fmt.Sprintf("%s was called with args %v", cmd.Name(), args)) - - // The last argument, which is not complete, should not be part of the list of arguments - toComplete := args[len(args)-1] - trimmedArgs := args[:len(args)-1] - - // Find the real command for which completion must be performed - finalCmd, finalArgs, err := cmd.Root().Find(trimmedArgs) - if err != nil { - // Unable to find the real command. E.g., helm invalidCmd - CompDebugln(fmt.Sprintf("Unable to find a command for arguments: %v", trimmedArgs)) - return - } - - CompDebugln(fmt.Sprintf("Found final command '%s', with finalArgs %v", finalCmd.Name(), finalArgs)) - - var flag *pflag.Flag - if !finalCmd.DisableFlagParsing { - // We only do flag completion if we are allowed to parse flags - // This is important for helm plugins which need to do their own flag completion. - flag, finalArgs, toComplete, err = checkIfFlagCompletion(finalCmd, finalArgs, toComplete) - if err != nil { - // Error while attempting to parse flags - CompErrorln(err.Error()) - return - } - } - - // Parse the flags and extract the arguments to prepare for calling the completion function - if err = finalCmd.ParseFlags(finalArgs); err != nil { - CompErrorln(fmt.Sprintf("Error while parsing flags from args %v: %s", finalArgs, err.Error())) - return - } - - // We only remove the flags from the arguments if DisableFlagParsing is not set. - // This is important for helm plugins, which need to receive all flags. - // The plugin completion code will do its own flag parsing. - if !finalCmd.DisableFlagParsing { - finalArgs = finalCmd.Flags().Args() - CompDebugln(fmt.Sprintf("Args without flags are '%v' with length %d", finalArgs, len(finalArgs))) - } - - // Find completion function for the flag or command - var key interface{} - var keyStr string - if flag != nil { - key = flag - keyStr = flag.Name - } else { - key = finalCmd - keyStr = finalCmd.Name() - } - completionFn, ok := validArgsFunctions[key] - if !ok { - CompErrorln(fmt.Sprintf("Dynamic completion not supported/needed for flag or command: %s", keyStr)) - return - } - - CompDebugln(fmt.Sprintf("Calling completion method for subcommand '%s' with args '%v' and toComplete '%s'", finalCmd.Name(), finalArgs, toComplete)) - completions, directive := completionFn(finalCmd, finalArgs, toComplete) - for _, comp := range completions { - // Print each possible completion to stdout for the completion script to consume. - fmt.Fprintln(out, comp) - } - - if directive > BashCompDirectiveError+BashCompDirectiveNoSpace+BashCompDirectiveNoFileComp { - directive = BashCompDirectiveDefault - } - - // As the last printout, print the completion directive for the - // completion script to parse. - // The directive integer must be that last character following a single : - // The completion script expects :directive - fmt.Fprintf(out, ":%d\n", directive) - - // Print some helpful info to stderr for the user to understand. - // Output from stderr should be ignored from the completion script. - fmt.Fprintf(os.Stderr, "Completion ended with directive: %s\n", directive.string()) - }, - } -} - -func isFlag(arg string) bool { - return len(arg) > 0 && arg[0] == '-' -} - -func checkIfFlagCompletion(finalCmd *cobra.Command, args []string, lastArg string) (*pflag.Flag, []string, string, error) { - var flagName string - trimmedArgs := args - flagWithEqual := false - if isFlag(lastArg) { - if index := strings.Index(lastArg, "="); index >= 0 { - flagName = strings.TrimLeft(lastArg[:index], "-") - lastArg = lastArg[index+1:] - flagWithEqual = true - } else { - return nil, nil, "", errors.New("Unexpected completion request for flag") - } - } - - if len(flagName) == 0 { - if len(args) > 0 { - prevArg := args[len(args)-1] - if isFlag(prevArg) { - // If the flag contains an = it means it has already been fully processed - if index := strings.Index(prevArg, "="); index < 0 { - flagName = strings.TrimLeft(prevArg, "-") - - // Remove the uncompleted flag or else Cobra could complain about - // an invalid value for that flag e.g., helm status --output j - trimmedArgs = args[:len(args)-1] - } - } - } - } - - if len(flagName) == 0 { - // Not doing flag completion - return nil, trimmedArgs, lastArg, nil - } - - flag := findFlag(finalCmd, flagName) - if flag == nil { - // Flag not supported by this command, nothing to complete - err := fmt.Errorf("Subcommand '%s' does not support flag '%s'", finalCmd.Name(), flagName) - return nil, nil, "", err - } - - if !flagWithEqual { - if len(flag.NoOptDefVal) != 0 { - // We had assumed dealing with a two-word flag but the flag is a boolean flag. - // In that case, there is no value following it, so we are not really doing flag completion. - // Reset everything to do argument completion. - trimmedArgs = args - flag = nil - } - } - - return flag, trimmedArgs, lastArg, nil -} - -func findFlag(cmd *cobra.Command, name string) *pflag.Flag { - flagSet := cmd.Flags() - if len(name) == 1 { - // First convert the short flag into a long flag - // as the cmd.Flag() search only accepts long flags - if short := flagSet.ShorthandLookup(name); short != nil { - CompDebugln(fmt.Sprintf("checkIfFlagCompletion: found flag '%s' which we will change to '%s'", name, short.Name)) - name = short.Name - } else { - set := cmd.InheritedFlags() - if short = set.ShorthandLookup(name); short != nil { - CompDebugln(fmt.Sprintf("checkIfFlagCompletion: found inherited flag '%s' which we will change to '%s'", name, short.Name)) - name = short.Name - } else { - return nil - } - } - } - return cmd.Flag(name) -} - -// CompDebug prints the specified string to the same file as where the -// completion script prints its logs. -// Note that completion printouts should never be on stdout as they would -// be wrongly interpreted as actual completion choices by the completion script. -func CompDebug(msg string) { - msg = fmt.Sprintf("[Debug] %s", msg) - - // Such logs are only printed when the user has set the environment - // variable BASH_COMP_DEBUG_FILE to the path of some file to be used. - if path := os.Getenv("BASH_COMP_DEBUG_FILE"); path != "" { - f, err := os.OpenFile(path, - os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) - if err == nil { - defer f.Close() - f.WriteString(msg) - } - } - - if debug { - // Must print to stderr for this not to be read by the completion script. - fmt.Fprintln(os.Stderr, msg) - } -} - -// CompDebugln prints the specified string with a newline at the end -// to the same file as where the completion script prints its logs. -// Such logs are only printed when the user has set the environment -// variable BASH_COMP_DEBUG_FILE to the path of some file to be used. -func CompDebugln(msg string) { - CompDebug(fmt.Sprintf("%s\n", msg)) -} - -// CompError prints the specified completion message to stderr. -func CompError(msg string) { - msg = fmt.Sprintf("[Error] %s", msg) - - CompDebug(msg) - - // If not already printed by the call to CompDebug(). - if !debug { - // Must print to stderr for this not to be read by the completion script. - fmt.Fprintln(os.Stderr, msg) - } -} - -// CompErrorln prints the specified completion message to stderr with a newline at the end. -func CompErrorln(msg string) { - CompError(fmt.Sprintf("%s\n", msg)) -} From 9249530b7739a738e16d5e46195c82df63f00127 Mon Sep 17 00:00:00 2001 From: ZouYu Date: Fri, 12 Jun 2020 09:29:58 +0800 Subject: [PATCH 49/66] Add unit test case Signed-off-by: ZouYu --- internal/urlutil/urlutil_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/urlutil/urlutil_test.go b/internal/urlutil/urlutil_test.go index 8e99c1bfb..82acc40fe 100644 --- a/internal/urlutil/urlutil_test.go +++ b/internal/urlutil/urlutil_test.go @@ -56,6 +56,9 @@ func TestEqual(t *testing.T) { {"/foo", "/foo", true}, {"/foo", "/foo/", true}, {"/foo/.", "/foo/", true}, + {"%/1234", "%/1234", true}, + {"%/1234", "%/123", false}, + {"/1234", "%/1234", false}, } { if tt.match != Equal(tt.a, tt.b) { t.Errorf("Expected %q==%q to be %t", tt.a, tt.b, tt.match) From aa033196692ea9c4416fbb3859bebf05aded6bef Mon Sep 17 00:00:00 2001 From: Adam Reese Date: Fri, 12 Jun 2020 08:39:26 -0700 Subject: [PATCH 50/66] fix(chartutil): do not set helpers.tpl filetype for vim Helpers filetype is not mustache Signed-off-by: Adam Reese --- pkg/chartutil/create.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pkg/chartutil/create.go b/pkg/chartutil/create.go index 0e87c7b47..e74761b3f 100644 --- a/pkg/chartutil/create.go +++ b/pkg/chartutil/create.go @@ -386,8 +386,7 @@ const defaultNotes = `1. Get the application URL by running these commands: {{- end }} ` -const defaultHelpers = `{{/* vim: set filetype=mustache: */}} -{{/* +const defaultHelpers = `{{/* Expand the name of the chart. */}} {{- define ".name" -}} From f7c882d55e26958d03c34c9718a964b9a8180da2 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Sun, 14 Jun 2020 11:29:29 -0400 Subject: [PATCH 51/66] feat(cmd): Subcommands for the completion command Making each shell a subcommand of the 'completion' has multiple advantages: - simplifies the code, - allows to have different flags for each shell, for example, a future `--no-descriptions` flag for fish only, - allows to tailor the help text per shell. Signed-off-by: Marc Khouzam --- cmd/helm/completion.go | 81 ++++++++++++++++++++++------------------ cmd/helm/load_plugins.go | 3 +- 2 files changed, 47 insertions(+), 37 deletions(-) diff --git a/cmd/helm/completion.go b/cmd/helm/completion.go index c1f7790bc..696021363 100644 --- a/cmd/helm/completion.go +++ b/cmd/helm/completion.go @@ -21,61 +21,70 @@ import ( "os" "path/filepath" - "github.com/pkg/errors" "github.com/spf13/cobra" + + "helm.sh/helm/v3/cmd/helm/require" ) const completionDesc = ` -Generate autocompletions script for Helm for the specified shell (bash or zsh). +Generate autocompletions script for Helm for the specified shell. +` +const bashCompDesc = ` +Generate the autocompletion script for Helm for the bash shell. -This command can generate shell autocompletions. e.g. +To load completions in your current shell session: +$ source <(helm completion bash) - $ helm completion bash +To load completions for every new session, execute once: +Linux: + $ helm completion bash > /etc/bash_completion.d/helm +MacOS: + $ helm completion bash > /usr/local/etc/bash_completion.d/helm +` -Can be sourced as such +const zshCompDesc = ` +Generate the autocompletion script for Helm for the zsh shell. - $ source <(helm completion bash) -` +To load completions in your current shell session: +$ source <(helm completion zsh) -var ( - completionShells = map[string]func(out io.Writer, cmd *cobra.Command) error{ - "bash": runCompletionBash, - "zsh": runCompletionZsh, - } -) +To load completions for every new session, execute once: +$ helm completion zsh > "${fpath[1]}/_helm" +` func newCompletionCmd(out io.Writer) *cobra.Command { - shells := []string{} - for s := range completionShells { - shells = append(shells, s) - } - cmd := &cobra.Command{ - Use: "completion SHELL", - Short: "generate autocompletions script for the specified shell (bash or zsh)", + Use: "completion", + Short: "generate autocompletions script for the specified shell", Long: completionDesc, + Args: require.NoArgs, + } + + bash := &cobra.Command{ + Use: "bash", + Short: "generate autocompletions script for bash", + Long: bashCompDesc, + Args: require.NoArgs, + DisableFlagsInUseLine: true, RunE: func(cmd *cobra.Command, args []string) error { - return runCompletion(out, cmd, args) + return runCompletionBash(out, cmd) }, - ValidArgs: shells, } - return cmd -} - -func runCompletion(out io.Writer, cmd *cobra.Command, args []string) error { - if len(args) == 0 { - return errors.New("shell not specified") - } - if len(args) > 1 { - return errors.New("too many arguments, expected only the shell type") - } - run, found := completionShells[args[0]] - if !found { - return errors.Errorf("unsupported shell type %q", args[0]) + zsh := &cobra.Command{ + Use: "zsh", + Short: "generate autocompletions script for zsh", + Long: zshCompDesc, + Args: require.NoArgs, + DisableFlagsInUseLine: true, + RunE: func(cmd *cobra.Command, args []string) error { + return runCompletionZsh(out, cmd) + }, } - return run(out, cmd) + cmd.AddCommand(bash, zsh) + + return cmd } func runCompletionBash(out io.Writer, cmd *cobra.Command) error { diff --git a/cmd/helm/load_plugins.go b/cmd/helm/load_plugins.go index e439c8407..a6e0c4eae 100644 --- a/cmd/helm/load_plugins.go +++ b/cmd/helm/load_plugins.go @@ -105,7 +105,8 @@ func loadPlugins(baseCmd *cobra.Command, out io.Writer) { // We only do this when necessary (for the "completion" and "__complete" commands) to avoid the // risk of a rogue plugin affecting Helm's normal behavior. subCmd, _, err := baseCmd.Find(os.Args[1:]) - if (err == nil && (subCmd.Name() == "completion" || subCmd.Name() == cobra.ShellCompRequestCmd)) || + if (err == nil && + ((subCmd.HasParent() && subCmd.Parent().Name() == "completion") || subCmd.Name() == cobra.ShellCompRequestCmd)) || /* for the tests */ subCmd == baseCmd.Root() { loadCompletionForPlugin(c, plug) } From 4c9972cb7260e6424890c8d839c53ddb5460a6c5 Mon Sep 17 00:00:00 2001 From: Eric Lemieux Date: Mon, 18 Nov 2019 10:19:53 -0500 Subject: [PATCH 52/66] Add HelmVersion to Capabilities Signed-off-by: Eric Lemieux --- pkg/chartutil/capabilities.go | 5 +++++ pkg/chartutil/capabilities_test.go | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/pkg/chartutil/capabilities.go b/pkg/chartutil/capabilities.go index ce968c5d7..adfe2363d 100644 --- a/pkg/chartutil/capabilities.go +++ b/pkg/chartutil/capabilities.go @@ -20,6 +20,8 @@ import ( apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" + + helmversion "helm.sh/helm/v3/internal/version" ) var ( @@ -34,6 +36,7 @@ var ( Minor: "18", }, APIVersions: DefaultVersionSet, + HelmVersion: helmversion.Get(), } ) @@ -43,6 +46,8 @@ type Capabilities struct { KubeVersion KubeVersion // APIversions are supported Kubernetes API versions. APIVersions VersionSet + // HelmVersion is the build information for this helm version + HelmVersion helmversion.BuildInfo } // KubeVersion is the Kubernetes version. diff --git a/pkg/chartutil/capabilities_test.go b/pkg/chartutil/capabilities_test.go index 416eea06d..489a472be 100644 --- a/pkg/chartutil/capabilities_test.go +++ b/pkg/chartutil/capabilities_test.go @@ -58,3 +58,11 @@ func TestDefaultCapabilities(t *testing.T) { t.Errorf("Expected default KubeVersion.Minor to be 16, got %q", kv.Minor) } } + +func TestDefaultCapabilitiesHelmVersion(t *testing.T) { + hv := DefaultCapabilities.HelmVersion + + if hv.Version != "v3.2" { + t.Errorf("Expected default HelmVerison to be v3.2, got %q", hv.Version) + } +} From b6bbe4f08bbb98eadd6c9cd726b08a5c639908b3 Mon Sep 17 00:00:00 2001 From: Matt Butcher Date: Mon, 15 Jun 2020 16:39:39 -0600 Subject: [PATCH 53/66] Improve the extractor and add tests (#8317) Signed-off-by: Matt Butcher --- pkg/plugin/installer/http_installer.go | 61 ++++++++++++++++++++- pkg/plugin/installer/http_installer_test.go | 30 ++++++++++ 2 files changed, 89 insertions(+), 2 deletions(-) diff --git a/pkg/plugin/installer/http_installer.go b/pkg/plugin/installer/http_installer.go index c07cad80a..28e50b72b 100644 --- a/pkg/plugin/installer/http_installer.go +++ b/pkg/plugin/installer/http_installer.go @@ -21,10 +21,12 @@ import ( "compress/gzip" "io" "os" + "path" "path/filepath" "regexp" "strings" + securejoin "github.com/cyphar/filepath-securejoin" "github.com/pkg/errors" "helm.sh/helm/v3/internal/third_party/dep/fs" @@ -118,7 +120,7 @@ func (i *HTTPInstaller) Install() error { } if err := i.extractor.Extract(pluginData, i.CacheDir); err != nil { - return err + return errors.Wrap(err, "extracting files from archive") } if !isPlugin(i.CacheDir) { @@ -148,6 +150,58 @@ func (i HTTPInstaller) Path() string { return helmpath.DataPath("plugins", i.PluginName) } +// CleanJoin resolves dest as a subpath of root. +// +// This function runs several security checks on the path, generating an error if +// the supplied `dest` looks suspicious or would result in dubious behavior on the +// filesystem. +// +// CleanJoin assumes that any attempt by `dest` to break out of the CWD is an attempt +// to be malicious. (If you don't care about this, use the securejoin-filepath library.) +// It will emit an error if it detects paths that _look_ malicious, operating on the +// assumption that we don't actually want to do anything with files that already +// appear to be nefarious. +// +// - The character `:` is considered illegal because it is a separator on UNIX and a +// drive designator on Windows. +// - The path component `..` is considered suspicions, and therefore illegal +// - The character \ (backslash) is treated as a path separator and is converted to /. +// - Beginning a path with a path separator is illegal +// - Rudimentary symlink protects are offered by SecureJoin. +func cleanJoin(root, dest string) (string, error) { + + // On Windows, this is a drive separator. On UNIX-like, this is the path list separator. + // In neither case do we want to trust a TAR that contains these. + if strings.Contains(dest, ":") { + return "", errors.New("path contains ':', which is illegal") + } + + // The Go tar library does not convert separators for us. + // We assume here, as we do elsewhere, that `\\` means a Windows path. + dest = strings.ReplaceAll(dest, "\\", "/") + + // We want to alert the user that something bad was attempted. Cleaning it + // is not a good practice. + for _, part := range strings.Split(dest, "/") { + if part == ".." { + return "", errors.New("path contains '..', which is illegal") + } + } + + // If a path is absolute, the creator of the TAR is doing something shady. + if path.IsAbs(dest) { + return "", errors.New("path is absolute, which is illegal") + } + + // SecureJoin will do some cleaning, as well as some rudimentary checking of symlinks. + newpath, err := securejoin.SecureJoin(root, dest) + if err != nil { + return "", err + } + + return filepath.ToSlash(newpath), nil +} + // Extract extracts compressed archives // // Implements Extractor. @@ -171,7 +225,10 @@ func (g *TarGzExtractor) Extract(buffer *bytes.Buffer, targetDir string) error { return err } - path := filepath.Join(targetDir, header.Name) + path, err := cleanJoin(targetDir, header.Name) + if err != nil { + return err + } switch header.Typeflag { case tar.TypeDir: diff --git a/pkg/plugin/installer/http_installer_test.go b/pkg/plugin/installer/http_installer_test.go index 99470ace6..3eb92ee77 100644 --- a/pkg/plugin/installer/http_installer_test.go +++ b/pkg/plugin/installer/http_installer_test.go @@ -277,3 +277,33 @@ func TestExtract(t *testing.T) { } } + +func TestCleanJoin(t *testing.T) { + for i, fixture := range []struct { + path string + expect string + expectError bool + }{ + {"foo/bar.txt", "/tmp/foo/bar.txt", false}, + {"/foo/bar.txt", "", true}, + {"./foo/bar.txt", "/tmp/foo/bar.txt", false}, + {"./././././foo/bar.txt", "/tmp/foo/bar.txt", false}, + {"../../../../foo/bar.txt", "", true}, + {"foo/../../../../bar.txt", "", true}, + {"c:/foo/bar.txt", "/tmp/c:/foo/bar.txt", true}, + {"foo\\bar.txt", "/tmp/foo/bar.txt", false}, + {"c:\\foo\\bar.txt", "", true}, + } { + out, err := cleanJoin("/tmp", fixture.path) + if err != nil { + if !fixture.expectError { + t.Errorf("Test %d: Path was not cleaned: %s", i, err) + } + continue + } + if fixture.expect != out { + t.Errorf("Test %d: Expected %q but got %q", i, fixture.expect, out) + } + } + +} From fd99c9055d3d2bbe2b5a790d5d355f496c4a73f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20R=C3=BCger?= Date: Tue, 16 Jun 2020 14:34:00 +0200 Subject: [PATCH 54/66] chore(Makefile): Remove unused variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dep was replaced by go mod Signed-off-by: Manuel Rüger --- Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile b/Makefile index 446fbc0ed..524421279 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,6 @@ TARGET_OBJS ?= darwin-amd64.tar.gz darwin-amd64.tar.gz.sha256 darwin-amd64.tar.g BINNAME ?= helm GOPATH = $(shell go env GOPATH) -DEP = $(GOPATH)/bin/dep GOX = $(GOPATH)/bin/gox GOIMPORTS = $(GOPATH)/bin/goimports ARCH = $(shell uname -p) From 561cc4280830af4a40f2e60c5f17fb3ee69b4e39 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Fri, 12 Jun 2020 08:24:55 -0400 Subject: [PATCH 55/66] feat(comp): Provide completion for --version flag This commit allows to use shell completion to obtain the list of available versions of a chart referenced in a 'repo/chart' format. It applies to: - helm install - helm template - helm upgrade - helm show - helm pull The 'repo/chart' argument must be present for completion to be triggered (or else we don't yet know which chart to fetch the versions for). The completion can be slow for the 'stable' repo because its index file takes some time to parse. Signed-off-by: Marc Khouzam --- cmd/helm/flags.go | 27 +++++++++++++ cmd/helm/install.go | 20 +++++++++- cmd/helm/install_test.go | 31 +++++++++++++++ cmd/helm/pull.go | 12 ++++++ cmd/helm/pull_test.go | 26 +++++++++++++ cmd/helm/show.go | 12 ++++++ cmd/helm/show_test.go | 38 +++++++++++++++++++ cmd/helm/template.go | 2 +- cmd/helm/template_test.go | 30 +++++++++++++++ cmd/helm/testdata/output/version-comp.txt | 5 +++ .../testdata/output/version-invalid-comp.txt | 2 + cmd/helm/upgrade.go | 12 ++++++ cmd/helm/upgrade_test.go | 26 +++++++++++++ 13 files changed, 240 insertions(+), 3 deletions(-) create mode 100644 cmd/helm/testdata/output/version-comp.txt create mode 100644 cmd/helm/testdata/output/version-invalid-comp.txt diff --git a/cmd/helm/flags.go b/cmd/helm/flags.go index d4cd88fef..040773d7b 100644 --- a/cmd/helm/flags.go +++ b/cmd/helm/flags.go @@ -19,6 +19,7 @@ package main import ( "fmt" "log" + "path/filepath" "strings" "github.com/spf13/cobra" @@ -27,7 +28,9 @@ import ( "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/cli/output" "helm.sh/helm/v3/pkg/cli/values" + "helm.sh/helm/v3/pkg/helmpath" "helm.sh/helm/v3/pkg/postrender" + "helm.sh/helm/v3/pkg/repo" ) const outputFlag = "output" @@ -127,3 +130,27 @@ func (p postRenderer) Set(s string) error { *p.renderer = pr return nil } + +func compVersionFlag(chartRef string, toComplete string) ([]string, cobra.ShellCompDirective) { + chartInfo := strings.Split(chartRef, "/") + if len(chartInfo) != 2 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + + repoName := chartInfo[0] + chartName := chartInfo[1] + + path := filepath.Join(settings.RepositoryCache, helmpath.CacheIndexFile(repoName)) + + var versions []string + if indexFile, err := repo.LoadIndexFile(path); err == nil { + for _, details := range indexFile.Entries[chartName] { + version := details.Metadata.Version + if strings.HasPrefix(version, toComplete) { + versions = append(versions, version) + } + } + } + + return versions, cobra.ShellCompDirectiveNoFileComp +} diff --git a/cmd/helm/install.go b/cmd/helm/install.go index b489c262d..9024add2f 100644 --- a/cmd/helm/install.go +++ b/cmd/helm/install.go @@ -19,6 +19,7 @@ package main import ( "fmt" "io" + "log" "time" "github.com/pkg/errors" @@ -126,14 +127,14 @@ func newInstallCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { }, } - addInstallFlags(cmd.Flags(), client, valueOpts) + addInstallFlags(cmd, cmd.Flags(), client, valueOpts) bindOutputFlag(cmd, &outfmt) bindPostRenderFlag(cmd, &client.PostRenderer) return cmd } -func addInstallFlags(f *pflag.FlagSet, client *action.Install, valueOpts *values.Options) { +func addInstallFlags(cmd *cobra.Command, f *pflag.FlagSet, client *action.Install, valueOpts *values.Options) { f.BoolVar(&client.CreateNamespace, "create-namespace", false, "create the release namespace if not present") f.BoolVar(&client.DryRun, "dry-run", false, "simulate an install") f.BoolVar(&client.DisableHooks, "no-hooks", false, "prevent hooks from running during install") @@ -151,6 +152,21 @@ func addInstallFlags(f *pflag.FlagSet, client *action.Install, valueOpts *values f.BoolVar(&client.SubNotes, "render-subchart-notes", false, "if set, render subchart notes along with the parent") addValueOptionsFlags(f, valueOpts) addChartPathOptionsFlags(f, &client.ChartPathOptions) + + err := cmd.RegisterFlagCompletionFunc("version", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + requiredArgs := 2 + if client.GenerateName { + requiredArgs = 1 + } + if len(args) != requiredArgs { + return nil, cobra.ShellCompDirectiveNoFileComp + } + return compVersionFlag(args[requiredArgs-1], toComplete) + }) + + if err != nil { + log.Fatal(err) + } } func runInstall(args []string, client *action.Install, valueOpts *values.Options, out io.Writer) (*release.Release, error) { diff --git a/cmd/helm/install_test.go b/cmd/helm/install_test.go index 7a101940f..36de648f9 100644 --- a/cmd/helm/install_test.go +++ b/cmd/helm/install_test.go @@ -17,6 +17,7 @@ limitations under the License. package main import ( + "fmt" "testing" ) @@ -208,3 +209,33 @@ func TestInstall(t *testing.T) { func TestInstallOutputCompletion(t *testing.T) { outputFlagCompletionTest(t, "install") } + +func TestInstallVersionCompletion(t *testing.T) { + repoFile := "testdata/helmhome/helm/repositories.yaml" + repoCache := "testdata/helmhome/helm/repository" + + repoSetup := fmt.Sprintf("--repository-config %s --repository-cache %s", repoFile, repoCache) + + tests := []cmdTestCase{{ + name: "completion for install version flag with release name", + cmd: fmt.Sprintf("%s __complete install releasename testing/alpine --version ''", repoSetup), + golden: "output/version-comp.txt", + }, { + name: "completion for install version flag with generate-name", + cmd: fmt.Sprintf("%s __complete install --generate-name testing/alpine --version ''", repoSetup), + golden: "output/version-comp.txt", + }, { + name: "completion for install version flag too few args", + cmd: fmt.Sprintf("%s __complete install testing/alpine --version ''", repoSetup), + golden: "output/version-invalid-comp.txt", + }, { + name: "completion for install version flag too many args", + cmd: fmt.Sprintf("%s __complete install releasename testing/alpine badarg --version ''", repoSetup), + golden: "output/version-invalid-comp.txt", + }, { + name: "completion for install version flag invalid chart", + cmd: fmt.Sprintf("%s __complete install releasename invalid/invalid --version ''", repoSetup), + golden: "output/version-invalid-comp.txt", + }} + runTestCmd(t, tests) +} diff --git a/cmd/helm/pull.go b/cmd/helm/pull.go index d10c629db..3f62bf0c7 100644 --- a/cmd/helm/pull.go +++ b/cmd/helm/pull.go @@ -19,6 +19,7 @@ package main import ( "fmt" "io" + "log" "github.com/spf13/cobra" @@ -82,5 +83,16 @@ func newPullCmd(out io.Writer) *cobra.Command { f.StringVarP(&client.DestDir, "destination", "d", ".", "location to write the chart. If this and tardir are specified, tardir is appended to this") addChartPathOptionsFlags(f, &client.ChartPathOptions) + err := cmd.RegisterFlagCompletionFunc("version", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) != 1 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + return compVersionFlag(args[0], toComplete) + }) + + if err != nil { + log.Fatal(err) + } + return cmd } diff --git a/cmd/helm/pull_test.go b/cmd/helm/pull_test.go index d4661f928..435df51f1 100644 --- a/cmd/helm/pull_test.go +++ b/cmd/helm/pull_test.go @@ -195,3 +195,29 @@ func TestPullCmd(t *testing.T) { }) } } + +func TestPullVersionCompletion(t *testing.T) { + repoFile := "testdata/helmhome/helm/repositories.yaml" + repoCache := "testdata/helmhome/helm/repository" + + repoSetup := fmt.Sprintf("--repository-config %s --repository-cache %s", repoFile, repoCache) + + tests := []cmdTestCase{{ + name: "completion for pull version flag", + cmd: fmt.Sprintf("%s __complete pull testing/alpine --version ''", repoSetup), + golden: "output/version-comp.txt", + }, { + name: "completion for pull version flag too few args", + cmd: fmt.Sprintf("%s __complete pull --version ''", repoSetup), + golden: "output/version-invalid-comp.txt", + }, { + name: "completion for pull version flag too many args", + cmd: fmt.Sprintf("%s __complete pull testing/alpine badarg --version ''", repoSetup), + golden: "output/version-invalid-comp.txt", + }, { + name: "completion for pull version flag invalid chart", + cmd: fmt.Sprintf("%s __complete pull invalid/invalid --version ''", repoSetup), + golden: "output/version-invalid-comp.txt", + }} + runTestCmd(t, tests) +} diff --git a/cmd/helm/show.go b/cmd/helm/show.go index c78069a09..c122d8476 100644 --- a/cmd/helm/show.go +++ b/cmd/helm/show.go @@ -19,6 +19,7 @@ package main import ( "fmt" "io" + "log" "github.com/spf13/cobra" @@ -151,6 +152,17 @@ func addShowFlags(subCmd *cobra.Command, client *action.Show) { f.BoolVar(&client.Devel, "devel", false, "use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored") addChartPathOptionsFlags(f, &client.ChartPathOptions) + + err := subCmd.RegisterFlagCompletionFunc("version", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) != 1 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + return compVersionFlag(args[0], toComplete) + }) + + if err != nil { + log.Fatal(err) + } } func runShow(args []string, client *action.Show) (string, error) { diff --git a/cmd/helm/show_test.go b/cmd/helm/show_test.go index 00d7c8145..6c550282f 100644 --- a/cmd/helm/show_test.go +++ b/cmd/helm/show_test.go @@ -80,3 +80,41 @@ func TestShowPreReleaseChart(t *testing.T) { }) } } + +func TestShowVersionCompletion(t *testing.T) { + repoFile := "testdata/helmhome/helm/repositories.yaml" + repoCache := "testdata/helmhome/helm/repository" + + repoSetup := fmt.Sprintf("--repository-config %s --repository-cache %s", repoFile, repoCache) + + tests := []cmdTestCase{{ + name: "completion for show version flag", + cmd: fmt.Sprintf("%s __complete show chart testing/alpine --version ''", repoSetup), + golden: "output/version-comp.txt", + }, { + name: "completion for show version flag too few args", + cmd: fmt.Sprintf("%s __complete show chart --version ''", repoSetup), + golden: "output/version-invalid-comp.txt", + }, { + name: "completion for show version flag too many args", + cmd: fmt.Sprintf("%s __complete show chart testing/alpine badarg --version ''", repoSetup), + golden: "output/version-invalid-comp.txt", + }, { + name: "completion for show version flag invalid chart", + cmd: fmt.Sprintf("%s __complete show chart invalid/invalid --version ''", repoSetup), + golden: "output/version-invalid-comp.txt", + }, { + name: "completion for show version flag with all", + cmd: fmt.Sprintf("%s __complete show all testing/alpine --version ''", repoSetup), + golden: "output/version-comp.txt", + }, { + name: "completion for show version flag with readme", + cmd: fmt.Sprintf("%s __complete show readme testing/alpine --version ''", repoSetup), + golden: "output/version-comp.txt", + }, { + name: "completion for show version flag with values", + cmd: fmt.Sprintf("%s __complete show values testing/alpine --version ''", repoSetup), + golden: "output/version-comp.txt", + }} + runTestCmd(t, tests) +} diff --git a/cmd/helm/template.go b/cmd/helm/template.go index 0fc29e189..83ad61f22 100644 --- a/cmd/helm/template.go +++ b/cmd/helm/template.go @@ -139,7 +139,7 @@ func newTemplateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { } f := cmd.Flags() - addInstallFlags(f, client, valueOpts) + addInstallFlags(cmd, f, client, valueOpts) f.StringArrayVarP(&showFiles, "show-only", "s", []string{}, "only show manifests rendered from the given templates") f.StringVar(&client.OutputDir, "output-dir", "", "writes the executed templates to files in output-dir instead of stdout") f.BoolVar(&validate, "validate", false, "validate your manifests against the Kubernetes cluster you are currently pointing at. This is the same validation performed on an install") diff --git a/cmd/helm/template_test.go b/cmd/helm/template_test.go index 92dd9825e..f8cd31347 100644 --- a/cmd/helm/template_test.go +++ b/cmd/helm/template_test.go @@ -124,3 +124,33 @@ func TestTemplateCmd(t *testing.T) { } runTestCmd(t, tests) } + +func TestTemplateVersionCompletion(t *testing.T) { + repoFile := "testdata/helmhome/helm/repositories.yaml" + repoCache := "testdata/helmhome/helm/repository" + + repoSetup := fmt.Sprintf("--repository-config %s --repository-cache %s", repoFile, repoCache) + + tests := []cmdTestCase{{ + name: "completion for template version flag with release name", + cmd: fmt.Sprintf("%s __complete template releasename testing/alpine --version ''", repoSetup), + golden: "output/version-comp.txt", + }, { + name: "completion for template version flag with generate-name", + cmd: fmt.Sprintf("%s __complete template --generate-name testing/alpine --version ''", repoSetup), + golden: "output/version-comp.txt", + }, { + name: "completion for template version flag too few args", + cmd: fmt.Sprintf("%s __complete template testing/alpine --version ''", repoSetup), + golden: "output/version-invalid-comp.txt", + }, { + name: "completion for template version flag too many args", + cmd: fmt.Sprintf("%s __complete template releasename testing/alpine badarg --version ''", repoSetup), + golden: "output/version-invalid-comp.txt", + }, { + name: "completion for template version flag invalid chart", + cmd: fmt.Sprintf("%s __complete template releasename invalid/invalid --version ''", repoSetup), + golden: "output/version-invalid-comp.txt", + }} + runTestCmd(t, tests) +} diff --git a/cmd/helm/testdata/output/version-comp.txt b/cmd/helm/testdata/output/version-comp.txt new file mode 100644 index 000000000..098e2cec2 --- /dev/null +++ b/cmd/helm/testdata/output/version-comp.txt @@ -0,0 +1,5 @@ +0.3.0-rc.1 +0.2.0 +0.1.0 +:4 +Completion ended with directive: ShellCompDirectiveNoFileComp diff --git a/cmd/helm/testdata/output/version-invalid-comp.txt b/cmd/helm/testdata/output/version-invalid-comp.txt new file mode 100644 index 000000000..8d9fad576 --- /dev/null +++ b/cmd/helm/testdata/output/version-invalid-comp.txt @@ -0,0 +1,2 @@ +:4 +Completion ended with directive: ShellCompDirectiveNoFileComp diff --git a/cmd/helm/upgrade.go b/cmd/helm/upgrade.go index 1db899eae..dc3bc9a58 100644 --- a/cmd/helm/upgrade.go +++ b/cmd/helm/upgrade.go @@ -19,6 +19,7 @@ package main import ( "fmt" "io" + "log" "time" "github.com/pkg/errors" @@ -188,5 +189,16 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { bindOutputFlag(cmd, &outfmt) bindPostRenderFlag(cmd, &client.PostRenderer) + err := cmd.RegisterFlagCompletionFunc("version", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) != 2 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + return compVersionFlag(args[1], toComplete) + }) + + if err != nil { + log.Fatal(err) + } + return cmd } diff --git a/cmd/helm/upgrade_test.go b/cmd/helm/upgrade_test.go index 6f260ae57..7e88bc0df 100644 --- a/cmd/helm/upgrade_test.go +++ b/cmd/helm/upgrade_test.go @@ -381,3 +381,29 @@ func prepareMockRelease(releaseName string, t *testing.T) (func(n string, v int, func TestUpgradeOutputCompletion(t *testing.T) { outputFlagCompletionTest(t, "upgrade") } + +func TestUpgradeVersionCompletion(t *testing.T) { + repoFile := "testdata/helmhome/helm/repositories.yaml" + repoCache := "testdata/helmhome/helm/repository" + + repoSetup := fmt.Sprintf("--repository-config %s --repository-cache %s", repoFile, repoCache) + + tests := []cmdTestCase{{ + name: "completion for upgrade version flag", + cmd: fmt.Sprintf("%s __complete upgrade releasename testing/alpine --version ''", repoSetup), + golden: "output/version-comp.txt", + }, { + name: "completion for upgrade version flag too few args", + cmd: fmt.Sprintf("%s __complete upgrade releasename --version ''", repoSetup), + golden: "output/version-invalid-comp.txt", + }, { + name: "completion for upgrade version flag too many args", + cmd: fmt.Sprintf("%s __complete upgrade releasename testing/alpine badarg --version ''", repoSetup), + golden: "output/version-invalid-comp.txt", + }, { + name: "completion for upgrade version flag invalid chart", + cmd: fmt.Sprintf("%s __complete upgrade releasename invalid/invalid --version ''", repoSetup), + golden: "output/version-invalid-comp.txt", + }} + runTestCmd(t, tests) +} From 569ad27f2bc16b7b407e8a464e70e70cac9a43a8 Mon Sep 17 00:00:00 2001 From: vitt-bagal <31851690+vitt-bagal@users.noreply.github.com> Date: Mon, 22 Jun 2020 20:50:54 +0530 Subject: [PATCH 56/66] remove s390x arch check Signed-off-by: vitthalb@us.ibm.com --- scripts/get-helm-3 | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/get-helm-3 b/scripts/get-helm-3 index 22a93aa0e..ce9411edc 100755 --- a/scripts/get-helm-3 +++ b/scripts/get-helm-3 @@ -33,7 +33,6 @@ initArch() { x86_64) ARCH="amd64";; i686) ARCH="386";; i386) ARCH="386";; - s390x) ARCH="s390x";; esac } From 148d94bcf781bdbf4c735ad0defdee15961389ec Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Tue, 23 Jun 2020 11:07:48 -0700 Subject: [PATCH 57/66] version bump Signed-off-by: Matthew Fisher --- .../helm/repository/test-name-charts.txt | 0 .../helm/repository/test-name-index.yaml | 3 + .../testdata/output/schema-negative-cli.txt | 2 +- cmd/helm/testdata/output/schema-negative.txt | 2 +- .../output/subchart-schema-cli-negative.txt | 2 +- go.mod | 32 +-- go.sum | 244 +++++++++++++++--- pkg/chartutil/jsonschema_test.go | 2 +- 8 files changed, 238 insertions(+), 49 deletions(-) create mode 100644 cmd/helm/testdata/helmhome/helm/repository/test-name-charts.txt create mode 100644 cmd/helm/testdata/helmhome/helm/repository/test-name-index.yaml diff --git a/cmd/helm/testdata/helmhome/helm/repository/test-name-charts.txt b/cmd/helm/testdata/helmhome/helm/repository/test-name-charts.txt new file mode 100644 index 000000000..e69de29bb diff --git a/cmd/helm/testdata/helmhome/helm/repository/test-name-index.yaml b/cmd/helm/testdata/helmhome/helm/repository/test-name-index.yaml new file mode 100644 index 000000000..895e79d39 --- /dev/null +++ b/cmd/helm/testdata/helmhome/helm/repository/test-name-index.yaml @@ -0,0 +1,3 @@ +apiVersion: v1 +entries: {} +generated: "2020-06-23T10:01:59.2530763-07:00" diff --git a/cmd/helm/testdata/output/schema-negative-cli.txt b/cmd/helm/testdata/output/schema-negative-cli.txt index 26bc92b1b..d6f096e14 100644 --- a/cmd/helm/testdata/output/schema-negative-cli.txt +++ b/cmd/helm/testdata/output/schema-negative-cli.txt @@ -1,4 +1,4 @@ Error: values don't meet the specifications of the schema(s) in the following chart(s): empty: -- age: Must be greater than or equal to 0/1 +- age: Must be greater than or equal to 0 diff --git a/cmd/helm/testdata/output/schema-negative.txt b/cmd/helm/testdata/output/schema-negative.txt index 2ea97b7d0..f7c89dd56 100644 --- a/cmd/helm/testdata/output/schema-negative.txt +++ b/cmd/helm/testdata/output/schema-negative.txt @@ -1,5 +1,5 @@ Error: values don't meet the specifications of the schema(s) in the following chart(s): empty: - (root): employmentInfo is required -- age: Must be greater than or equal to 0/1 +- age: Must be greater than or equal to 0 diff --git a/cmd/helm/testdata/output/subchart-schema-cli-negative.txt b/cmd/helm/testdata/output/subchart-schema-cli-negative.txt index 86f6e87a2..c0883a8e8 100644 --- a/cmd/helm/testdata/output/subchart-schema-cli-negative.txt +++ b/cmd/helm/testdata/output/subchart-schema-cli-negative.txt @@ -1,4 +1,4 @@ Error: values don't meet the specifications of the schema(s) in the following chart(s): subchart-with-schema: -- age: Must be greater than or equal to 0/1 +- age: Must be greater than or equal to 0 diff --git a/go.mod b/go.mod index f23d152a2..08eae92fa 100644 --- a/go.mod +++ b/go.mod @@ -7,10 +7,10 @@ require ( github.com/DATA-DOG/go-sqlmock v1.4.1 github.com/Masterminds/semver/v3 v3.1.0 github.com/Masterminds/sprig/v3 v3.1.0 - github.com/Masterminds/squirrel v1.2.0 + github.com/Masterminds/squirrel v1.4.0 github.com/Masterminds/vcs v1.13.1 - github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496 - github.com/containerd/containerd v1.3.2 + github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 + github.com/containerd/containerd v1.3.4 github.com/cyphar/filepath-securejoin v0.2.2 github.com/deislabs/oras v0.8.1 github.com/docker/distribution v2.7.1+incompatible @@ -21,26 +21,26 @@ require ( github.com/gofrs/flock v0.7.1 github.com/gosuri/uitable v0.0.4 github.com/jmoiron/sqlx v1.2.0 - github.com/lib/pq v1.3.0 + github.com/lib/pq v1.7.0 github.com/mattn/go-shellwords v1.0.10 github.com/mitchellh/copystructure v1.0.0 - github.com/opencontainers/go-digest v1.0.0-rc1 + github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec v1.0.1 github.com/pkg/errors v0.9.1 - github.com/rubenv/sql-migrate v0.0.0-20200212082348-64f95ea68aa3 - github.com/sirupsen/logrus v1.4.2 + github.com/rubenv/sql-migrate v0.0.0-20200616145509-8d140a17f351 + github.com/sirupsen/logrus v1.6.0 github.com/spf13/cobra v1.0.0 github.com/spf13/pflag v1.0.5 - github.com/stretchr/testify v1.5.1 - github.com/xeipuuv/gojsonschema v1.1.0 - golang.org/x/crypto v0.0.0-20200414173820-0848c9571904 - k8s.io/api v0.18.2 - k8s.io/apiextensions-apiserver v0.18.2 - k8s.io/apimachinery v0.18.2 - k8s.io/cli-runtime v0.18.2 - k8s.io/client-go v0.18.2 + github.com/stretchr/testify v1.6.1 + github.com/xeipuuv/gojsonschema v1.2.0 + golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 + k8s.io/api v0.18.4 + k8s.io/apiextensions-apiserver v0.18.4 + k8s.io/apimachinery v0.18.4 + k8s.io/cli-runtime v0.18.4 + k8s.io/client-go v0.18.4 k8s.io/klog v1.0.0 - k8s.io/kubectl v0.18.2 + k8s.io/kubectl v0.18.4 sigs.k8s.io/yaml v1.2.0 ) diff --git a/go.sum b/go.sum index 2908f3eb8..0d0ef8c83 100644 --- a/go.sum +++ b/go.sum @@ -25,6 +25,7 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/DATA-DOG/go-sqlmock v1.4.1 h1:ThlnYciV1iM/V0OSF/dtkqWb6xo5qITT1TJBG1MRDJM= github.com/DATA-DOG/go-sqlmock v1.4.1/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd h1:sjQovDkwrZp8u+gxLtPgKGjk5hCxuy2hrRejBTA9xFU= github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E= github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg= @@ -33,8 +34,8 @@ github.com/Masterminds/semver/v3 v3.1.0 h1:Y2lUDsFKVRSYGojLJ1yLxSXdMmMYTYls0rCvo github.com/Masterminds/semver/v3 v3.1.0/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/sprig/v3 v3.1.0 h1:j7GpgZ7PdFqNsmncycTHsLmVPf5/3wJtlgW9TNDYD9Y= github.com/Masterminds/sprig/v3 v3.1.0/go.mod h1:ONGMf7UfYGAbMXCZmQLy8x3lCDIPrEZE/rU8pmrbihA= -github.com/Masterminds/squirrel v1.2.0 h1:K1NhbTO21BWG47IVR0OnIZuE0LZcXAYqywrC3Ko53KI= -github.com/Masterminds/squirrel v1.2.0/go.mod h1:yaPeOnPG5ZRwL9oKdTsO/prlkPbXWZlRVMQ/gGlzIuA= +github.com/Masterminds/squirrel v1.4.0 h1:he5i/EXixZxrBUWcxzDYMiju9WZ3ld/l7QBNuo/eN3w= +github.com/Masterminds/squirrel v1.4.0/go.mod h1:yaPeOnPG5ZRwL9oKdTsO/prlkPbXWZlRVMQ/gGlzIuA= github.com/Masterminds/vcs v1.13.1 h1:NL3G1X7/7xduQtA2sJLpVpfHTNBALVNSjob6KEjPXNQ= github.com/Masterminds/vcs v1.13.1/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA= github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 h1:ygIc8M6trr62pF5DucadTWGdEB4mEyvzi0e2nbcmcyA= @@ -52,21 +53,37 @@ github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= -github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496 h1:zV3ejI06GQ59hwDQAvmK1qxOQGB3WuVTRoY0okPTAv0= -github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= +github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 h1:4daAzAu0S6Vi7/lbWECcX0j45yZReDZ56BQsrVBOEEY= +github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= +github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= +github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bitly/go-simplejson v0.5.0 h1:6IH+V8/tVMab511d5bn4M7EwGXZf9Hj6i2xSwkNEM+Y= github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= @@ -82,23 +99,35 @@ github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b h1:otBG+dV+YK+Soembj github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o= github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= +github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= +github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= +github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f h1:tSNMc+rJDfmYntojat8lljbt1mgKNpTxUZJsSzJ9Y1s= github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko= github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/containerd v1.3.2 h1:ForxmXkA6tPIvffbrDAcPUIB32QgXkt2XFj+F0UxetA= github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.3.4 h1:3o0smo5SKY7H6AJCmJhsnCjR2/V2T8VmiHt7seN2/kI= +github.com/containerd/containerd v1.3.4/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20200107194136-26c1120b8d41 h1:kIFnQBO7rQ0XkMe6xEwbybYHBEaWmh/f++laI6Emt7M= github.com/containerd/continuity v0.0.0-20200107194136-26c1120b8d41/go.mod h1:Dq467ZllaHgAtVp4p1xUQWBrFXR9s/wyoTpG8zOJGkY= +github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448 h1:PUD50EuOMkXVcpBIA/R95d56duJR9VxhwncsFbNnxW4= github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= +github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de h1:dlfGmNcE3jDAecLqwKPMNX6nk2qh1c1Vg1/YTzpOOF4= github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= +github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd h1:JNn81o/xG+8NEo3bC/vx9pbi/g2WI8mtP2/nXzu297Y= github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -113,6 +142,7 @@ github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfc github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= @@ -153,13 +183,19 @@ github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96 h1:cenwrSVm+Z7QL github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/evanphx/json-patch v4.2.0+incompatible h1:fUDGZCv/7iAN7u0puUVhvKCcsR6vRfwrJatElLBEf0I= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M= github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= @@ -168,6 +204,8 @@ github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZM github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= +github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7 h1:LofdAjjjqCSXMwLGgOgnE+rdPuvX9DxCqaHwKy7i/ko= @@ -179,8 +217,11 @@ github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0 github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= @@ -245,9 +286,12 @@ github.com/gobuffalo/packr/v2 v2.7.1/go.mod h1:qYEvAazPaVxy7Y7KR0W8qYEE+RymX74kE github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= +github.com/godror/godror v0.13.3/go.mod h1:2ouUT4kdhUBk7TAkHWD4SN0CdI0pgEQbo8FVHhbSKWg= github.com/gofrs/flock v0.7.1 h1:DP+LD/t0njgoPBvT5MJLeliUIVQR03hiKR6vezdwHlc= github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= @@ -258,6 +302,8 @@ github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903 h1:LbsanbbD6LieF github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -265,6 +311,7 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450/go.mod h1:Bk6SMAONeMXrxql8uvOKuAZSu8aM5RUGv+1C6IJaEho= github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995/go.mod h1:lJgMEyOkYFkPcDKwRXegd+iM6E7matEszMG5HhwytU8= github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk= @@ -273,6 +320,7 @@ github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= @@ -281,6 +329,7 @@ github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -292,10 +341,14 @@ github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTV github.com/gophercloud/gophercloud v0.1.0 h1:P/nh25+rzXouhytV2pUHBb65fnds26Ghl8/391+sT5o= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33 h1:893HsJqtxp9z1SF76gg6hY70hRY1wVlTSnC/h1yUDCo= github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.2 h1:zoNxOV7WjqXptQOVngLmcSQgXmgk4NMz1HibBchjl/I= github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gosuri/uitable v0.0.4 h1:IG2xLKRvErL3uhY6e1BylFzG+aJiwQviDDTfOKeKTpY= @@ -307,25 +360,44 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= +github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.3.1 h1:4jgBlKK6tLKFvO8u5pmYjG91cqytmDCDvGh7ECVFfFs= github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ= github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA= github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= @@ -344,6 +416,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -357,11 +431,14 @@ github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhR github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU= -github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.7.0 h1:h93mCPfUSkaul3Ka/VG8uZdmW1uMHDGxzu0NWHuJmHY= +github.com/lib/pq v1.7.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= +github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= +github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -376,6 +453,7 @@ github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaO github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-oci8 v0.0.7/go.mod h1:wjDx6Xm9q7dFtHJvIlrI99JytznLw5wQ4R+9mNXJwGI= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= @@ -386,12 +464,18 @@ github.com/mattn/go-sqlite3 v1.12.0 h1:u/x3mp++qUxvYfulZ4HKOvVO0JWhk7HtE8lWhbGz/ github.com/mattn/go-sqlite3 v1.12.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f h1:2+myh5ml7lgEU/51gbeLHfKGNfgEQQIWrlbdaOsidbQ= github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= @@ -409,84 +493,128 @@ github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8m github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= +github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= +github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw= github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI= github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v0.1.1 h1:GlxAyO6x8rfZYN9Tt0Kti5a/cP41iuiO2yYT0IJGY8Y= github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700 h1:eNUVfm/RFLIi1G7flU5/ZRTHvd4kcVuzfRnL6OFlzCI= github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs= +github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= +github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc= github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= +github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0 h1:vrDKnkGzuGvhNAL56c7DBz29ZL+KxnoR0x7enabFceM= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.3.0 h1:miYCvYqFXtl/J9FIy8eNpBfYthAEFg+Ys0XyUVEcDsc= +github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.7.0 h1:L+1lyG48J1zAQXA3RBX/nG/B3gjlHq0zTt2tlbJLyCY= +github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQlL8= github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= +github.com/prometheus/procfs v0.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLkt8= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.4.0 h1:LUa41nrWTQNGhzdsZ5lTnkwbNjj6rXTdazA1cSdjkOY= github.com/rogpeppe/go-internal v1.4.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rubenv/sql-migrate v0.0.0-20200212082348-64f95ea68aa3 h1:xkBtI5JktwbW/vf4vopBbhYsRFTGfQWHYXzC0/qYwxI= -github.com/rubenv/sql-migrate v0.0.0-20200212082348-64f95ea68aa3/go.mod h1:rtQlpHw+eR6UrqaS3kX1VYeaCxzCVdimDS7g5Ln4pPc= +github.com/rubenv/sql-migrate v0.0.0-20200616145509-8d140a17f351 h1:HXr/qUllAWv9riaI4zh2eXWKmCSDqVS/XH1MRHLKRwk= +github.com/rubenv/sql-migrate v0.0.0-20200616145509-8d140a17f351/go.mod h1:DCgfY80j8GYL7MLEfvcpSFvjD0L5yZq/aZUJmhZklyg= github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= @@ -495,9 +623,13 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= @@ -520,8 +652,12 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= +github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -529,6 +665,9 @@ github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJy github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8 h1:zLV6q4e8Jv9EHjNg/iHfzwDkCve6Ua5jCygptrtXHvI= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= @@ -537,14 +676,15 @@ github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGr github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= -github.com/xeipuuv/gojsonschema v1.1.0 h1:ngVtJC9TY/lg0AA/1k48FYhBrhRoFlEmWzsehpNAaZg= -github.com/xeipuuv/gojsonschema v1.1.0/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= +github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xlab/handysort v0.0.0-20150421192137-fb3537ed64a1/go.mod h1:QcJo0QPSfTONNIgpN5RA8prR7fF8nkF6cTWTcNerRO8= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= @@ -562,42 +702,62 @@ go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mI go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2 h1:75k/FF0Q2YM8QYo07VPddOLBslDt1MZOdEslOHvmzAs= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d h1:9FCpayM9Egr1baVnV1SX0H87m+XB0B8S0hAMi99X/3U= golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947M/+gp0+CqQXDtMRC0fseo= golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200414173820-0848c9571904 h1:bXoxMPcSLOq08zI3/c5dEBT6lE4eh+jOh886GHrn6V8= golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -628,8 +788,10 @@ golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -641,11 +803,14 @@ golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3 h1:7TYNF4UdlohbFwpNH04CoPMp1cHUZgO1Ebq5r2hIjfo= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7 h1:HmbHVPwrPEKPGLAcHSrMe6+hqSUlvZU0rab6x5EXfGU= golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191220142924-d4481acd189f h1:68K/z8GLUxV76xGSqwTWw2gyk/jwn79LUL43rES2g8o= +golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -655,7 +820,10 @@ golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -668,14 +836,21 @@ golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191004055002-72853e10c5a3/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM= @@ -685,12 +860,16 @@ google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoA google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= @@ -706,6 +885,7 @@ gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qS gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/gorp.v1 v1.7.2 h1:j3DWlAyGVv8whO7AcIWznQ2Yj7yJkn34B8s63GViAAw= gopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw= @@ -716,6 +896,7 @@ gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -723,37 +904,41 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -k8s.io/api v0.18.2 h1:wG5g5ZmSVgm5B+eHMIbI9EGATS2L8Z72rda19RIEgY8= -k8s.io/api v0.18.2/go.mod h1:SJCWI7OLzhZSvbY7U8zwNl9UA4o1fizoug34OV/2r78= -k8s.io/apiextensions-apiserver v0.18.2 h1:I4v3/jAuQC+89L3Z7dDgAiN4EOjN6sbm6iBqQwHTah8= -k8s.io/apiextensions-apiserver v0.18.2/go.mod h1:q3faSnRGmYimiocj6cHQ1I3WpLqmDgJFlKL37fC4ZvY= -k8s.io/apimachinery v0.18.2 h1:44CmtbmkzVDAhCpRVSiP2R5PPrC2RtlIv/MoB8xpdRA= -k8s.io/apimachinery v0.18.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA= -k8s.io/apiserver v0.18.2/go.mod h1:Xbh066NqrZO8cbsoenCwyDJ1OSi8Ag8I2lezeHxzwzw= -k8s.io/cli-runtime v0.18.2 h1:JiTN5RgkFNTiMxHBRyrl6n26yKWAuNRlei1ZJALUmC8= -k8s.io/cli-runtime v0.18.2/go.mod h1:yfFR2sQQzDsV0VEKGZtrJwEy4hLZ2oj4ZIfodgxAHWQ= -k8s.io/client-go v0.18.2 h1:aLB0iaD4nmwh7arT2wIn+lMnAq7OswjaejkQ8p9bBYE= -k8s.io/client-go v0.18.2/go.mod h1:Xcm5wVGXX9HAA2JJ2sSBUn3tCJ+4SVlCbl2MNNv+CIU= -k8s.io/code-generator v0.18.2/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRVkTc= -k8s.io/component-base v0.18.2 h1:SJweNZAGcUvsypLGNPNGeJ9UgPZQ6+bW+gEHe8uyh/Y= -k8s.io/component-base v0.18.2/go.mod h1:kqLlMuhJNHQ9lz8Z7V5bxUUtjFZnrypArGl58gmDfUM= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +k8s.io/api v0.18.4 h1:8x49nBRxuXGUlDlwlWd3RMY1SayZrzFfxea3UZSkFw4= +k8s.io/api v0.18.4/go.mod h1:lOIQAKYgai1+vz9J7YcDZwC26Z0zQewYOGWdyIPUUQ4= +k8s.io/apiextensions-apiserver v0.18.4 h1:Y3HGERmS8t9u12YNUFoOISqefaoGRuTc43AYCLzWmWE= +k8s.io/apiextensions-apiserver v0.18.4/go.mod h1:NYeyeYq4SIpFlPxSAB6jHPIdvu3hL0pc36wuRChybio= +k8s.io/apimachinery v0.18.4 h1:ST2beySjhqwJoIFk6p7Hp5v5O0hYY6Gngq/gUYXTPIA= +k8s.io/apimachinery v0.18.4/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko= +k8s.io/apiserver v0.18.4/go.mod h1:q+zoFct5ABNnYkGIaGQ3bcbUNdmPyOCoEBcg51LChY8= +k8s.io/cli-runtime v0.18.4 h1:IUx7quIOb4gbQ4M+B1ksF/PTBovQuL5tXWzplX3t+FM= +k8s.io/cli-runtime v0.18.4/go.mod h1:9/hS/Cuf7NVzWR5F/5tyS6xsnclxoPLVtwhnkJG1Y4g= +k8s.io/client-go v0.18.4 h1:un55V1Q/B3JO3A76eS0kUSywgGK/WR3BQ8fHQjNa6Zc= +k8s.io/client-go v0.18.4/go.mod h1:f5sXwL4yAZRkAtzOxRWUhA/N8XzGCb+nPZI8PfobZ9g= +k8s.io/code-generator v0.18.4/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c= +k8s.io/component-base v0.18.4 h1:Kr53Fp1iCGNsl9Uv4VcRvLy7YyIqi9oaJOQ7SXtKI98= +k8s.io/component-base v0.18.4/go.mod h1:7jr/Ef5PGmKwQhyAz/pjByxJbC58mhKAhiaDu0vXfPk= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= -k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c h1:/KUFqjjqAcY4Us6luF5RDNZ16KJtb49HfR3ZHB9qYXM= -k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= -k8s.io/kubectl v0.18.2 h1:9jnGSOC2DDVZmMUTMi0D1aed438mfQcgqa5TAzVjA1k= -k8s.io/kubectl v0.18.2/go.mod h1:OdgFa3AlsPKRpFFYE7ICTwulXOcMGXHTc+UKhHKvrb4= +k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6 h1:Oh3Mzx5pJ+yIumsAD0MOECPVeXsVot0UkiaCGVyfGQY= +k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= +k8s.io/kubectl v0.18.4 h1:l9DUYPTEMs1+qNtoqPpTyaJOosvj7l7tQqphCO1K52s= +k8s.io/kubectl v0.18.4/go.mod h1:EzB+nfeUWk6fm6giXQ8P4Fayw3dsN+M7Wjy23mTRtB0= k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= -k8s.io/metrics v0.18.2/go.mod h1:qga8E7QfYNR9Q89cSCAjinC9pTZ7yv1XSVGUB0vJypg= +k8s.io/metrics v0.18.4/go.mod h1:luze4fyI9JG4eLDZy0kFdYEebqNfi0QrG4xNEbPkHOs= k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89 h1:d4vVOjXm687F1iLSP2q3lyPPuyvTUt3aVoBpi2DqRsU= k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0= @@ -766,4 +951,5 @@ sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj6uzU2+8OWDFv/HxUSs7kI= diff --git a/pkg/chartutil/jsonschema_test.go b/pkg/chartutil/jsonschema_test.go index 33f009259..a0acd5a7f 100644 --- a/pkg/chartutil/jsonschema_test.go +++ b/pkg/chartutil/jsonschema_test.go @@ -56,7 +56,7 @@ func TestValidateAgainstSingleSchemaNegative(t *testing.T) { } expectedErrString := `- (root): employmentInfo is required -- age: Must be greater than or equal to 0/1 +- age: Must be greater than or equal to 0 ` if errString != expectedErrString { t.Errorf("Error string :\n`%s`\ndoes not match expected\n`%s`", errString, expectedErrString) From 4f136861d397ec37b18c92ceee8027333ba1bc24 Mon Sep 17 00:00:00 2001 From: ShenXinkang <610716076@qq.com> Date: Tue, 9 Jun 2020 13:57:43 +0800 Subject: [PATCH 58/66] fix template command use --show-only flags error in windows environment Signed-off-by: ShenXinkang <610716076@qq.com> --- cmd/helm/template.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cmd/helm/template.go b/cmd/helm/template.go index 83ad61f22..9ea61b17a 100644 --- a/cmd/helm/template.go +++ b/cmd/helm/template.go @@ -102,6 +102,8 @@ func newTemplateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { var manifestsToRender []string for _, f := range showFiles { missing := true + // Use linux-style filepath separators to unify user's input path + f = filepath.ToSlash(f) for _, manifestKey := range manifestsKeys { manifest := splitManifests[manifestKey] submatch := manifestNameRegex.FindStringSubmatch(manifest) @@ -112,7 +114,9 @@ func newTemplateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { // manifest.Name is rendered using linux-style filepath separators on Windows as // well as macOS/linux. manifestPathSplit := strings.Split(manifestName, "/") - manifestPath := filepath.Join(manifestPathSplit...) + // manifest.Path is connected using linux-style filepath separators on Windows as + // well as macOS/linux + manifestPath := strings.Join(manifestPathSplit, "/") // if the filepath provided matches a manifest path in the // chart, render that manifest From 05beedd671027b227b44968e6a961be5b200a465 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Sun, 28 Jun 2020 19:53:29 -0400 Subject: [PATCH 59/66] feat(comp): Complete revision for rollback command Signed-off-by: Marc Khouzam --- cmd/helm/get_all.go | 2 +- cmd/helm/get_hooks.go | 2 +- cmd/helm/get_manifest.go | 2 +- cmd/helm/get_notes.go | 2 +- cmd/helm/get_values.go | 2 +- cmd/helm/history.go | 10 ++++-- cmd/helm/rollback.go | 11 ++++-- cmd/helm/rollback_test.go | 36 +++++++++++++++++++ cmd/helm/status.go | 2 +- cmd/helm/testdata/output/revision-comp.txt | 4 +-- cmd/helm/testdata/output/rollback-comp.txt | 4 +++ .../output/rollback-wrong-args-comp.txt | 2 ++ 12 files changed, 65 insertions(+), 14 deletions(-) create mode 100644 cmd/helm/testdata/output/rollback-comp.txt create mode 100644 cmd/helm/testdata/output/rollback-wrong-args-comp.txt diff --git a/cmd/helm/get_all.go b/cmd/helm/get_all.go index 1ebc7e387..a5037e4df 100644 --- a/cmd/helm/get_all.go +++ b/cmd/helm/get_all.go @@ -67,7 +67,7 @@ func newGetAllCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { f.IntVar(&client.Version, "revision", 0, "get the named release with revision") err := cmd.RegisterFlagCompletionFunc("revision", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if len(args) == 1 { - return compListRevisions(cfg, args[0]) + return compListRevisions(toComplete, cfg, args[0]) } return nil, cobra.ShellCompDirectiveNoFileComp }) diff --git a/cmd/helm/get_hooks.go b/cmd/helm/get_hooks.go index 6453c30eb..8b78653b5 100644 --- a/cmd/helm/get_hooks.go +++ b/cmd/helm/get_hooks.go @@ -62,7 +62,7 @@ func newGetHooksCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { cmd.Flags().IntVar(&client.Version, "revision", 0, "get the named release with revision") err := cmd.RegisterFlagCompletionFunc("revision", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if len(args) == 1 { - return compListRevisions(cfg, args[0]) + return compListRevisions(toComplete, cfg, args[0]) } return nil, cobra.ShellCompDirectiveNoFileComp }) diff --git a/cmd/helm/get_manifest.go b/cmd/helm/get_manifest.go index 048bf36b0..8ffeb3676 100644 --- a/cmd/helm/get_manifest.go +++ b/cmd/helm/get_manifest.go @@ -62,7 +62,7 @@ func newGetManifestCmd(cfg *action.Configuration, out io.Writer) *cobra.Command cmd.Flags().IntVar(&client.Version, "revision", 0, "get the named release with revision") err := cmd.RegisterFlagCompletionFunc("revision", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if len(args) == 1 { - return compListRevisions(cfg, args[0]) + return compListRevisions(toComplete, cfg, args[0]) } return nil, cobra.ShellCompDirectiveNoFileComp }) diff --git a/cmd/helm/get_notes.go b/cmd/helm/get_notes.go index 88d494fc4..a9d29ce49 100644 --- a/cmd/helm/get_notes.go +++ b/cmd/helm/get_notes.go @@ -61,7 +61,7 @@ func newGetNotesCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { f.IntVar(&client.Version, "revision", 0, "get the named release with revision") err := cmd.RegisterFlagCompletionFunc("revision", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if len(args) == 1 { - return compListRevisions(cfg, args[0]) + return compListRevisions(toComplete, cfg, args[0]) } return nil, cobra.ShellCompDirectiveNoFileComp }) diff --git a/cmd/helm/get_values.go b/cmd/helm/get_values.go index fa7b10fed..c8c87c033 100644 --- a/cmd/helm/get_values.go +++ b/cmd/helm/get_values.go @@ -65,7 +65,7 @@ func newGetValuesCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { f.IntVar(&client.Version, "revision", 0, "get the named release with revision") err := cmd.RegisterFlagCompletionFunc("revision", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if len(args) == 1 { - return compListRevisions(cfg, args[0]) + return compListRevisions(toComplete, cfg, args[0]) } return nil, cobra.ShellCompDirectiveNoFileComp }) diff --git a/cmd/helm/history.go b/cmd/helm/history.go index b49c52990..f55eea9fd 100644 --- a/cmd/helm/history.go +++ b/cmd/helm/history.go @@ -20,6 +20,7 @@ import ( "fmt" "io" "strconv" + "strings" "time" "github.com/gosuri/uitable" @@ -184,15 +185,18 @@ func min(x, y int) int { return y } -func compListRevisions(cfg *action.Configuration, releaseName string) ([]string, cobra.ShellCompDirective) { +func compListRevisions(toComplete string, cfg *action.Configuration, releaseName string) ([]string, cobra.ShellCompDirective) { client := action.NewHistory(cfg) var revisions []string if hist, err := client.Run(releaseName); err == nil { for _, release := range hist { - revisions = append(revisions, strconv.Itoa(release.Version)) + version := strconv.Itoa(release.Version) + if strings.HasPrefix(version, toComplete) { + revisions = append(revisions, version) + } } - return revisions, cobra.ShellCompDirectiveDefault + return revisions, cobra.ShellCompDirectiveNoFileComp } return nil, cobra.ShellCompDirectiveError } diff --git a/cmd/helm/rollback.go b/cmd/helm/rollback.go index 3b336d0ff..4849913a1 100644 --- a/cmd/helm/rollback.go +++ b/cmd/helm/rollback.go @@ -47,10 +47,15 @@ func newRollbackCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { Long: rollbackDesc, Args: require.MinimumNArgs(1), ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - if len(args) != 0 { - return nil, cobra.ShellCompDirectiveNoFileComp + if len(args) == 0 { + return compListReleases(toComplete, cfg) } - return compListReleases(toComplete, cfg) + + if len(args) == 1 { + return compListRevisions(toComplete, cfg, args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp }, RunE: func(cmd *cobra.Command, args []string) error { if len(args) > 1 { diff --git a/cmd/helm/rollback_test.go b/cmd/helm/rollback_test.go index fdc627b5f..c11a7fca6 100644 --- a/cmd/helm/rollback_test.go +++ b/cmd/helm/rollback_test.go @@ -68,3 +68,39 @@ func TestRollbackCmd(t *testing.T) { }} runTestCmd(t, tests) } + +func TestRollbackRevisionCompletion(t *testing.T) { + mk := func(name string, vers int, status release.Status) *release.Release { + return release.Mock(&release.MockReleaseOptions{ + Name: name, + Version: vers, + Status: status, + }) + } + + releases := []*release.Release{ + mk("musketeers", 11, release.StatusDeployed), + mk("musketeers", 10, release.StatusSuperseded), + mk("musketeers", 9, release.StatusSuperseded), + mk("musketeers", 8, release.StatusSuperseded), + mk("carabins", 1, release.StatusSuperseded), + } + + tests := []cmdTestCase{{ + name: "completion for release parameter", + cmd: "__complete rollback ''", + rels: releases, + golden: "output/rollback-comp.txt", + }, { + name: "completion for revision parameter", + cmd: "__complete rollback musketeers ''", + rels: releases, + golden: "output/revision-comp.txt", + }, { + name: "completion for with too many args", + cmd: "__complete rollback musketeers 11 ''", + rels: releases, + golden: "output/rollback-wrong-args-comp.txt", + }} + runTestCmd(t, tests) +} diff --git a/cmd/helm/status.go b/cmd/helm/status.go index 5913d08df..abd32a9c2 100644 --- a/cmd/helm/status.go +++ b/cmd/helm/status.go @@ -78,7 +78,7 @@ func newStatusCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { err := cmd.RegisterFlagCompletionFunc("revision", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if len(args) == 1 { - return compListRevisions(cfg, args[0]) + return compListRevisions(toComplete, cfg, args[0]) } return nil, cobra.ShellCompDirectiveNoFileComp }) diff --git a/cmd/helm/testdata/output/revision-comp.txt b/cmd/helm/testdata/output/revision-comp.txt index d06947d9d..50f7a9092 100644 --- a/cmd/helm/testdata/output/revision-comp.txt +++ b/cmd/helm/testdata/output/revision-comp.txt @@ -2,5 +2,5 @@ 9 10 11 -:0 -Completion ended with directive: ShellCompDirectiveDefault +:4 +Completion ended with directive: ShellCompDirectiveNoFileComp diff --git a/cmd/helm/testdata/output/rollback-comp.txt b/cmd/helm/testdata/output/rollback-comp.txt new file mode 100644 index 000000000..f7741af12 --- /dev/null +++ b/cmd/helm/testdata/output/rollback-comp.txt @@ -0,0 +1,4 @@ +carabins +musketeers +:4 +Completion ended with directive: ShellCompDirectiveNoFileComp diff --git a/cmd/helm/testdata/output/rollback-wrong-args-comp.txt b/cmd/helm/testdata/output/rollback-wrong-args-comp.txt new file mode 100644 index 000000000..8d9fad576 --- /dev/null +++ b/cmd/helm/testdata/output/rollback-wrong-args-comp.txt @@ -0,0 +1,2 @@ +:4 +Completion ended with directive: ShellCompDirectiveNoFileComp From 7ec501155d082d2e2cc314d7fd03729b5873f21c Mon Sep 17 00:00:00 2001 From: Guangwen Feng Date: Mon, 29 Jun 2020 15:20:23 +0800 Subject: [PATCH 60/66] Fix golint issue Signed-off-by: Guangwen Feng --- internal/experimental/registry/client_opts.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/experimental/registry/client_opts.go b/internal/experimental/registry/client_opts.go index 76b527492..e2f742aec 100644 --- a/internal/experimental/registry/client_opts.go +++ b/internal/experimental/registry/client_opts.go @@ -61,7 +61,7 @@ func ClientOptCache(cache *Cache) ClientOption { } } -// ClientOptCache returns a function that sets the cache setting on a client options set +// ClientOptCredentialsFile returns a function that sets the cache setting on a client options set func ClientOptCredentialsFile(credentialsFile string) ClientOption { return func(client *Client) { client.credentialsFile = credentialsFile From c6a00e63ef638c14be5560534c339484e35eb7ba Mon Sep 17 00:00:00 2001 From: zouyu Date: Mon, 29 Jun 2020 16:36:27 +0800 Subject: [PATCH 61/66] Fix some go-lint warnings Signed-off-by: zouyu --- pkg/postrender/postrender.go | 2 +- pkg/storage/storage.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/postrender/postrender.go b/pkg/postrender/postrender.go index 76f0f5a74..3af384290 100644 --- a/pkg/postrender/postrender.go +++ b/pkg/postrender/postrender.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -// package postrender contains an interface that can be implemented for custom +// Package postrender contains an interface that can be implemented for custom // post-renderers and an exec implementation that can be used for arbitrary // binaries and scripts package postrender diff --git a/pkg/storage/storage.go b/pkg/storage/storage.go index c195120cd..2dfa3f615 100644 --- a/pkg/storage/storage.go +++ b/pkg/storage/storage.go @@ -27,7 +27,7 @@ import ( "helm.sh/helm/v3/pkg/storage/driver" ) -// The type field of the Kubernetes storage object which stores the Helm release +// HelmStorageType is the type field of the Kubernetes storage object which stores the Helm release // version. It is modified slightly replacing the '/': sh.helm/release.v1 // Note: The version 'v1' is incremented if the release object metadata is // modified between major releases. From 7e9a83184c32864d3d296f3439bb8ffbc1c0d3a3 Mon Sep 17 00:00:00 2001 From: Peter Engelbert <36644727+pmengelbert@users.noreply.github.com> Date: Mon, 29 Jun 2020 16:55:01 -0500 Subject: [PATCH 62/66] Determine chart digest by manifest (#8249) Currently, whenever the chart is printed, the digest of the .tar.gz content layer is printed as the digest. The manifest digest is important for OCI purposes, particularly in pushing to a registry. Resolves #8248. Signed-off-by: Peter Engelbert --- internal/experimental/registry/client.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/experimental/registry/client.go b/internal/experimental/registry/client.go index 540eddfa3..5756030c0 100644 --- a/internal/experimental/registry/client.go +++ b/internal/experimental/registry/client.go @@ -240,7 +240,7 @@ func (c *Client) PrintChartTable() error { // printCacheRefSummary prints out chart ref summary func (c *Client) printCacheRefSummary(r *CacheRefSummary) { fmt.Fprintf(c.out, "ref: %s\n", r.Name) - fmt.Fprintf(c.out, "digest: %s\n", r.Digest.Hex()) + fmt.Fprintf(c.out, "digest: %s\n", r.Manifest.Digest.Hex()) fmt.Fprintf(c.out, "size: %s\n", byteCountBinary(r.Size)) fmt.Fprintf(c.out, "name: %s\n", r.Chart.Metadata.Name) fmt.Fprintf(c.out, "version: %s\n", r.Chart.Metadata.Version) @@ -257,7 +257,7 @@ func (c *Client) getChartTableRows() ([][]interface{}, error) { refsMap[r.Name] = map[string]string{ "name": r.Chart.Metadata.Name, "version": r.Chart.Metadata.Version, - "digest": shortDigest(r.Digest.Hex()), + "digest": shortDigest(r.Manifest.Digest.Hex()), "size": byteCountBinary(r.Size), "created": timeAgo(r.CreatedAt), } From 863588ca69209153863f72327fe8c818c963904a Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Tue, 9 Jun 2020 11:44:04 -0700 Subject: [PATCH 63/66] fix(cmd): display warnings on stderr The warnings introduced when a chart has been deprecated is displayed on standard out. This is a regression for users piping the output of `helm template` from a deprecated chart to `kubectl`. This changes the error message to display on standard error instead. Signed-off-by: Matthew Fisher --- cmd/helm/helm.go | 5 +++++ cmd/helm/install.go | 3 +-- cmd/helm/testdata/output/deprecated-chart.txt | 1 - cmd/helm/upgrade.go | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/cmd/helm/helm.go b/cmd/helm/helm.go index fcc7315f5..d4e82bb01 100644 --- a/cmd/helm/helm.go +++ b/cmd/helm/helm.go @@ -56,6 +56,11 @@ func debug(format string, v ...interface{}) { } } +func warning(format string, v ...interface{}) { + format = fmt.Sprintf("WARNING: %s\n", format) + fmt.Fprintf(os.Stderr, format, v...) +} + func initKubeLogs() { pflag.CommandLine.SetNormalizeFunc(wordSepNormalizeFunc) gofs := flag.NewFlagSet("klog", flag.ExitOnError) diff --git a/cmd/helm/install.go b/cmd/helm/install.go index 9024add2f..cdb38a10a 100644 --- a/cmd/helm/install.go +++ b/cmd/helm/install.go @@ -17,7 +17,6 @@ limitations under the License. package main import ( - "fmt" "io" "log" "time" @@ -207,7 +206,7 @@ func runInstall(args []string, client *action.Install, valueOpts *values.Options } if chartRequested.Metadata.Deprecated { - fmt.Fprintln(out, "WARNING: This chart is deprecated") + warning("This chart is deprecated") } if req := chartRequested.Metadata.Dependencies; req != nil { diff --git a/cmd/helm/testdata/output/deprecated-chart.txt b/cmd/helm/testdata/output/deprecated-chart.txt index e5be2c3f1..039d6aef6 100644 --- a/cmd/helm/testdata/output/deprecated-chart.txt +++ b/cmd/helm/testdata/output/deprecated-chart.txt @@ -1,4 +1,3 @@ -WARNING: This chart is deprecated NAME: aeneas LAST DEPLOYED: Fri Sep 2 22:04:05 1977 NAMESPACE: default diff --git a/cmd/helm/upgrade.go b/cmd/helm/upgrade.go index dc3bc9a58..c992e2f6b 100644 --- a/cmd/helm/upgrade.go +++ b/cmd/helm/upgrade.go @@ -148,7 +148,7 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { } if ch.Metadata.Deprecated { - fmt.Fprintln(out, "WARNING: This chart is deprecated") + warning("This chart is deprecated") } rel, err := client.Run(args[0], ch, vals) From 4ad76e1be278bdf8b842c3775f34301cbed08b72 Mon Sep 17 00:00:00 2001 From: Bridget Kromhout Date: Mon, 6 Jul 2020 14:57:41 -0500 Subject: [PATCH 64/66] Updating for today's actual milestone practices Signed-off-by: Bridget Kromhout --- CONTRIBUTING.md | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e27fa7d19..e4493d24c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -96,22 +96,16 @@ that we're already aware of. It is also worth asking on the Slack channels. ## Milestones -We use milestones to track progress of releases. There are also 2 special milestones used for -helping us keep work organized: `Upcoming - Minor` and `Upcoming - Major` - -`Upcoming - Minor` is used for keeping track of issues that aren't assigned to a specific release -but could easily be addressed in a minor release. `Upcoming - Major` keeps track of issues that will -need to be addressed in a major release. For example, if the current version is `3.2.0` an issue/PR -could fall in to one of 4 different active milestones: `3.2.1`, `3.3.0`, `Upcoming - Minor`, or -`Upcoming - Major`. If an issue pertains to a specific upcoming bug or minor release, it would go -into `3.2.1` or `3.3.0`. If the issue/PR does not have a specific milestone yet, but it is likely -that it will land in a `3.X` release, it should go into `Upcoming - Minor`. If the issue/PR is a -large functionality add or change and/or it breaks compatibility, then it should be added to the -`Upcoming - Major` milestone. An issue that we are not sure we will be doing will not be added to -any milestone. - -A milestone (and hence release) is considered done when all outstanding issues/PRs have been closed -or moved to another milestone. +We use milestones to track progress of specific planned releases. + +For example, if the latest currently-released version is `3.2.1`, an issue/PR which pertains to a +specific upcoming bugfix or feature release could fall into one of two different active milestones: +`3.2.2` or `3.3.0`. + +An issue that we are not sure we will be addressing will not be added to any milestone. + +A milestone (and hence release) can be closed when all outstanding issues/PRs have been closed +or moved to another milestone and the associated release has been published. ## Semantic Versioning From 3d05f96b7e505e1f36c3f0f2842d021d879f3231 Mon Sep 17 00:00:00 2001 From: Bridget Kromhout Date: Mon, 6 Jul 2020 19:43:01 -0500 Subject: [PATCH 65/66] Adding v4 link Signed-off-by: Bridget Kromhout --- CONTRIBUTING.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e4493d24c..a8028dd01 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -102,7 +102,9 @@ For example, if the latest currently-released version is `3.2.1`, an issue/PR wh specific upcoming bugfix or feature release could fall into one of two different active milestones: `3.2.2` or `3.3.0`. -An issue that we are not sure we will be addressing will not be added to any milestone. +Issues and PRs which are deemed backwards-incompatible may be added to the discussion items for +Helm 4 with [label:v4.x](https://github.com/helm/helm/labels/v4.x). An issue or PR that we are not +sure we will be addressing will not be added to any milestone. A milestone (and hence release) can be closed when all outstanding issues/PRs have been closed or moved to another milestone and the associated release has been published. From ceff32d5f8aa173549426625b608137a47981447 Mon Sep 17 00:00:00 2001 From: DongGang Date: Tue, 7 Jul 2020 23:44:22 +0800 Subject: [PATCH 66/66] fix(template):Issue:helm template with --output-dir (#8156) * fix(template):Issue:helm template with --output-dir doesn't write template with a hook to file Close #7836 Signed-off-by: Dong Gang * fix go file style Signed-off-by: Dong Gang * fix go file style Signed-off-by: Dong Gang --- cmd/helm/template.go | 6 ------ pkg/action/action.go | 20 +++++++++++++++++++- pkg/action/install.go | 2 +- pkg/action/install_test.go | 6 ++++++ pkg/action/upgrade.go | 2 +- 5 files changed, 27 insertions(+), 9 deletions(-) diff --git a/cmd/helm/template.go b/cmd/helm/template.go index 9ea61b17a..5a8a25102 100644 --- a/cmd/helm/template.go +++ b/cmd/helm/template.go @@ -80,12 +80,6 @@ func newTemplateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { var manifests bytes.Buffer fmt.Fprintln(&manifests, strings.TrimSpace(rel.Manifest)) - if !client.DisableHooks { - for _, m := range rel.Hooks { - fmt.Fprintf(&manifests, "---\n# Source: %s\n%s\n", m.Path, m.Manifest) - } - } - // if we have a list of files to render, then check that each of the // provided files exists in the chart. if len(showFiles) > 0 { diff --git a/pkg/action/action.go b/pkg/action/action.go index bb9ef5f71..698ebd23f 100644 --- a/pkg/action/action.go +++ b/pkg/action/action.go @@ -97,7 +97,7 @@ type Configuration struct { // renderResources renders the templates in a chart // // TODO: This function is badly in need of a refactor. -func (c *Configuration) renderResources(ch *chart.Chart, values chartutil.Values, releaseName, outputDir string, subNotes, useReleaseName, includeCrds bool, pr postrender.PostRenderer, dryRun bool) ([]*release.Hook, *bytes.Buffer, string, error) { +func (c *Configuration) renderResources(ch *chart.Chart, values chartutil.Values, releaseName, outputDir string, subNotes, useReleaseName, includeCrds bool, disableHooks bool, pr postrender.PostRenderer, dryRun bool) ([]*release.Hook, *bytes.Buffer, string, error) { hs := []*release.Hook{} b := bytes.NewBuffer(nil) @@ -210,6 +210,24 @@ func (c *Configuration) renderResources(ch *chart.Chart, values chartutil.Values } } + if !disableHooks && len(hs) > 0 { + for _, h := range hs { + if outputDir == "" { + fmt.Fprintf(b, "---\n# Source: %s\n%s\n", h.Path, h.Manifest) + } else { + newDir := outputDir + if useReleaseName { + newDir = filepath.Join(outputDir, releaseName) + } + err = writeToFile(newDir, h.Path, h.Manifest, fileWritten[h.Path]) + if err != nil { + return hs, b, "", err + } + fileWritten[h.Path] = true + } + } + } + if pr != nil { b, err = pr.Run(b) if err != nil { diff --git a/pkg/action/install.go b/pkg/action/install.go index 00fb208b0..48a3aeeca 100644 --- a/pkg/action/install.go +++ b/pkg/action/install.go @@ -236,7 +236,7 @@ func (i *Install) Run(chrt *chart.Chart, vals map[string]interface{}) (*release. rel := i.createRelease(chrt, vals) 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, i.DryRun) + rel.Hooks, manifestDoc, rel.Info.Notes, err = i.cfg.renderResources(chrt, valuesToRender, i.ReleaseName, i.OutputDir, i.SubNotes, i.UseReleaseName, i.IncludeCRDs, i.DisableHooks, i.PostRenderer, i.DryRun) // Even for errors, attach this if available if manifestDoc != nil { rel.Manifest = manifestDoc.String() diff --git a/pkg/action/install_test.go b/pkg/action/install_test.go index 6c4012cfd..4366889ce 100644 --- a/pkg/action/install_test.go +++ b/pkg/action/install_test.go @@ -499,6 +499,9 @@ func TestInstallReleaseOutputDir(t *testing.T) { _, err = os.Stat(filepath.Join(dir, "hello/templates/with-partials")) is.NoError(err) + _, err = os.Stat(filepath.Join(dir, "hello/templates/hooks")) + is.NoError(err) + _, err = os.Stat(filepath.Join(dir, "hello/templates/rbac")) is.NoError(err) @@ -539,6 +542,9 @@ func TestInstallOutputDirWithReleaseName(t *testing.T) { _, err = os.Stat(filepath.Join(newDir, "hello/templates/with-partials")) is.NoError(err) + _, err = os.Stat(filepath.Join(newDir, "hello/templates/hooks")) + is.NoError(err) + _, err = os.Stat(filepath.Join(newDir, "hello/templates/rbac")) is.NoError(err) diff --git a/pkg/action/upgrade.go b/pkg/action/upgrade.go index fc289dbab..921a0eba5 100644 --- a/pkg/action/upgrade.go +++ b/pkg/action/upgrade.go @@ -217,7 +217,7 @@ func (u *Upgrade) prepareUpgrade(name string, chart *chart.Chart, vals map[strin return nil, nil, err } - hooks, manifestDoc, notesTxt, err := u.cfg.renderResources(chart, valuesToRender, "", "", u.SubNotes, false, false, u.PostRenderer, u.DryRun) + hooks, manifestDoc, notesTxt, err := u.cfg.renderResources(chart, valuesToRender, "", "", u.SubNotes, false, false, false, u.PostRenderer, u.DryRun) if err != nil { return nil, nil, err }