From 7247956b96d0f038195af41f1be9b7ce6002c662 Mon Sep 17 00:00:00 2001 From: Pete Hodgson Date: Tue, 23 Jul 2019 09:48:17 -0700 Subject: [PATCH 01/12] Fix broken link in docs/related.md Looks like this hackernoon link is now broken, probably from when they moved off of Medium. Signed-off-by: Pete Hodgson --- docs/related.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/related.md b/docs/related.md index 06527d75d..63919790b 100644 --- a/docs/related.md +++ b/docs/related.md @@ -14,7 +14,7 @@ or [pull request](https://github.com/helm/helm/pulls). - [GitLab, Consumer Driven Contracts, Helm and Kubernetes](https://medium.com/@enxebre/gitlab-consumer-driven-contracts-helm-and-kubernetes-b7235a60a1cb#.xwp1y4tgi) - [Honestbee's Helm Chart Conventions](https://gist.github.com/so0k/f927a4b60003cedd101a0911757c605a) - [Releasing backward-incompatible changes: Kubernetes, Jenkins, Prometheus Operator, Helm and Traefik](https://medium.com/@enxebre/releasing-backward-incompatible-changes-kubernetes-jenkins-plugin-prometheus-operator-helm-self-6263ca61a1b1#.e0c7elxhq) -- [The Missing CI/CD Kubernetes Component: Helm package manager](https://hackernoon.com/the-missing-ci-cd-kubernetes-component-helm-package-manager-1fe002aac680#.691sk2zhu) +- [The Missing CI/CD Kubernetes Component: Helm package manager](https://medium.com/@gajus/the-missing-ci-cd-kubernetes-component-helm-package-manager-1fe002aac680) - [Using Helm to Deploy to Kubernetes](https://daemonza.github.io/2017/02/20/using-helm-to-deploy-to-kubernetes/) - [Writing a Helm Chart](https://www.influxdata.com/packaged-kubernetes-deployments-writing-helm-chart/) - [A basic walk through Kubernetes Helm](https://github.com/muffin87/helm-tutorial) From 276bb9b1c8ee3c51064f768e8c0e2fb64c3fd5f2 Mon Sep 17 00:00:00 2001 From: Tariq Ibrahim Date: Wed, 24 Jul 2019 16:22:46 -0700 Subject: [PATCH 02/12] fix golint issues reported by make test Signed-off-by: Tariq Ibrahim --- pkg/kube/client.go | 18 +++++++++++++----- pkg/kube/client_test.go | 2 +- pkg/lint/rules/chartfile.go | 4 ++-- pkg/tiller/environment/environment.go | 1 + 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/pkg/kube/client.go b/pkg/kube/client.go index fcaa28760..8fbfba1fd 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -314,7 +314,14 @@ func (c *Client) Get(namespace string, reader io.Reader) (string, error) { return buf.String(), nil } -// Deprecated; use UpdateWithOptions instead +// Update reads the current configuration and a target configuration from io.reader +// and creates resources that don't already exist, updates resources that have been modified +// in the target configuration and deletes resources from the current configuration that are +// not present in the target configuration. +// +// Namespace will set the namespaces. +// +// Deprecated: use UpdateWithOptions instead. func (c *Client) Update(namespace string, originalReader, targetReader io.Reader, force bool, recreate bool, timeout int64, shouldWait bool) error { return c.UpdateWithOptions(namespace, originalReader, targetReader, UpdateOptions{ Force: force, @@ -334,12 +341,13 @@ type UpdateOptions struct { CleanupOnFail bool } -// UpdateWithOptions reads in the current configuration and a target configuration from io.reader -// and creates resources that don't already exists, updates resources that have been modified +// UpdateWithOptions reads the current configuration and a target configuration from io.reader +// and creates resources that don't already exist, updates resources that have been modified // in the target configuration and deletes resources from the current configuration that are // not present in the target configuration. // -// Namespace will set the namespaces. +// Namespace will set the namespaces. UpdateOptions provides additional parameters to control +// update behavior. func (c *Client) UpdateWithOptions(namespace string, originalReader, targetReader io.Reader, opts UpdateOptions) error { original, err := c.BuildUnstructured(namespace, originalReader) if err != nil { @@ -552,7 +560,7 @@ func (c *Client) WatchUntilReady(namespace string, reader io.Reader, timeout int return perform(infos, c.watchTimeout(time.Duration(timeout)*time.Second)) } -// WatchUntilCRDEstablished polls the given CRD until it reaches the established +// WaitUntilCRDEstablished polls the given CRD until it reaches the established // state. A CRD needs to reach the established state before CRs can be created. // // If a naming conflict condition is found, this function will return an error. diff --git a/pkg/kube/client_test.go b/pkg/kube/client_test.go index 6faea02d0..d33b4b9d9 100644 --- a/pkg/kube/client_test.go +++ b/pkg/kube/client_test.go @@ -558,7 +558,7 @@ func TestWaitUntilCRDEstablished(t *testing.T) { } else { crd = crdWithConditions } - requestCount += 1 + requestCount++ return newResponse(200, &crd) }), } diff --git a/pkg/lint/rules/chartfile.go b/pkg/lint/rules/chartfile.go index 8ef33d0c5..8f6c16d94 100644 --- a/pkg/lint/rules/chartfile.go +++ b/pkg/lint/rules/chartfile.go @@ -51,7 +51,7 @@ func Chartfile(linter *support.Linter) { linter.RunLinterRule(support.ErrorSev, chartFileName, validateChartNameDirMatch(linter.ChartDir, chartFile)) // Chart metadata - linter.RunLinterRule(support.ErrorSev, chartFileName, validateChartApiVersion(chartFile)) + linter.RunLinterRule(support.ErrorSev, chartFileName, validateChartAPIVersion(chartFile)) linter.RunLinterRule(support.ErrorSev, chartFileName, validateChartVersion(chartFile)) linter.RunLinterRule(support.ErrorSev, chartFileName, validateChartEngine(chartFile)) linter.RunLinterRule(support.ErrorSev, chartFileName, validateChartMaintainer(chartFile)) @@ -97,7 +97,7 @@ func validateChartNameDirMatch(chartDir string, cf *chart.Metadata) error { return nil } -func validateChartApiVersion(cf *chart.Metadata) error { +func validateChartAPIVersion(cf *chart.Metadata) error { if cf.ApiVersion == "" { return errors.New("apiVersion is required") } diff --git a/pkg/tiller/environment/environment.go b/pkg/tiller/environment/environment.go index d84ad55db..83ec5e647 100644 --- a/pkg/tiller/environment/environment.go +++ b/pkg/tiller/environment/environment.go @@ -255,6 +255,7 @@ func (p *PrintingKubeClient) WaitAndGetCompletedPodPhase(namespace string, reade return v1.PodUnknown, err } +// WaitUntilCRDEstablished implements KubeClient WaitUntilCRDEstablished. func (p *PrintingKubeClient) WaitUntilCRDEstablished(reader io.Reader, timeout time.Duration) error { _, err := io.Copy(p.Out, reader) return err From c086f78583f1996939b73ab8dfdb6f24f0cb1488 Mon Sep 17 00:00:00 2001 From: ethan Date: Thu, 25 Jul 2019 22:36:25 +0800 Subject: [PATCH 03/12] cleanup: error message typos in sql.go Signed-off-by: ethan --- pkg/storage/driver/sql.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/storage/driver/sql.go b/pkg/storage/driver/sql.go index 46bcccc32..be2962da4 100644 --- a/pkg/storage/driver/sql.go +++ b/pkg/storage/driver/sql.go @@ -199,7 +199,7 @@ func (s *SQL) Query(labels map[string]string) ([]*rspb.Release, error) { sqlFilter[dbField] = val } else { s.Log("unknown label %s", key) - return nil, fmt.Errorf("unknow label %s", key) + return nil, fmt.Errorf("unknown label %s", key) } } sort.Strings(sqlFilterKeys) From e0e6a7acb6090d1b248a6aa1126a54a140537c23 Mon Sep 17 00:00:00 2001 From: Art Begolli Date: Fri, 26 Jul 2019 16:06:10 +0100 Subject: [PATCH 04/12] feat(): initial json output functionality --- cmd/helm/search.go | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/cmd/helm/search.go b/cmd/helm/search.go index 99ffafbd3..79ff91f97 100644 --- a/cmd/helm/search.go +++ b/cmd/helm/search.go @@ -17,6 +17,7 @@ limitations under the License. package main import ( + "encoding/json" "fmt" "io" "strings" @@ -48,6 +49,14 @@ type searchCmd struct { regexp bool version string colWidth uint + output string +} + +type ResultEntry struct { + Name string `json:"name"` + ChartVersion string `json:"chartVersion"` + AppVersion string `json:"appVersion"` + Description string `json:"description"` } func newSearchCmd(out io.Writer) *cobra.Command { @@ -68,6 +77,7 @@ func newSearchCmd(out io.Writer) *cobra.Command { f.BoolVarP(&sc.versions, "versions", "l", false, "Show the long listing, with each version of each chart on its own line") f.StringVarP(&sc.version, "version", "v", "", "Search using semantic versioning constraints") f.UintVar(&sc.colWidth, "col-width", 60, "Specifies the max column width of output") + f.StringVarP(&sc.output, "output", "o", "", "Show the output in specified format") return cmd } @@ -95,6 +105,12 @@ func (s *searchCmd) run(args []string) error { return err } + if s.output == "json" { + formattedResults, _ := s.formatSearchResultsJson(data, s.colWidth) + fmt.Fprintln(s.out, formattedResults) + return nil + } + fmt.Fprintln(s.out, s.formatSearchResults(data, s.colWidth)) return nil @@ -141,6 +157,28 @@ func (s *searchCmd) formatSearchResults(res []*search.Result, colWidth uint) str return table.String() } +func (s *searchCmd) formatSearchResultsJson(res []*search.Result, colWidth uint) (string, error) { + if len(res) == 0 { + return "No results found", nil + } + resultJson := []ResultEntry{} + for _, r := range res { + resultRow := ResultEntry{ + Name: r.Name, + ChartVersion: r.Chart.Version, + AppVersion: r.Chart.AppVersion, + Description: r.Chart.Description, + } + resultJson = append(resultJson, resultRow) + } + json, err := json.MarshalIndent(resultJson, "", " ") + if err != nil { + return "", err + } + + return string(json), nil +} + func (s *searchCmd) buildIndex() (*search.Index, error) { // Load the repositories.yaml rf, err := repo.LoadRepositoriesFile(s.helmhome.RepositoryFile()) From f3d57f6f24ba86da08fc6e20bc2688509c65e6ae Mon Sep 17 00:00:00 2001 From: Art Begolli Date: Fri, 26 Jul 2019 17:49:07 +0100 Subject: [PATCH 05/12] feat(): adding unit test for json flag --- cmd/helm/search_test.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cmd/helm/search_test.go b/cmd/helm/search_test.go index 233f94572..6a1e84f24 100644 --- a/cmd/helm/search_test.go +++ b/cmd/helm/search_test.go @@ -84,6 +84,12 @@ func TestSearchCmd(t *testing.T) { flags: []string{"--regexp"}, err: true, }, + { + name: "search for 'alpine', expect two matches in json", + args: []string{"alpine"}, + flags: []string{"--output", "json"}, + expected: "[\n {\n \"name\": \"testing/alpine\",\n \"chartVersion\": \"0.2.0\",\n \"appVersion\": \"2.3.4\",\n \"description\": \"Deploy a basic Alpine Linux pod\"\n }\n]\n", + }, } cleanup := resetEnv() From b27d6bb9109747b5f5a3e26ea201ff90bbfc9ee3 Mon Sep 17 00:00:00 2001 From: Art Begolli Date: Fri, 26 Jul 2019 17:57:19 +0100 Subject: [PATCH 06/12] feat(): updating array to json --- cmd/helm/search.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cmd/helm/search.go b/cmd/helm/search.go index 79ff91f97..1a136cb2f 100644 --- a/cmd/helm/search.go +++ b/cmd/helm/search.go @@ -59,6 +59,10 @@ type ResultEntry struct { Description string `json:"description"` } +type Results struct { + SearchResults []ResultEntry `json:"searchResults"` +} + func newSearchCmd(out io.Writer) *cobra.Command { sc := &searchCmd{out: out} @@ -171,7 +175,7 @@ func (s *searchCmd) formatSearchResultsJson(res []*search.Result, colWidth uint) } resultJson = append(resultJson, resultRow) } - json, err := json.MarshalIndent(resultJson, "", " ") + json, err := json.MarshalIndent(Results{SearchResults: resultJson}, "", " ") if err != nil { return "", err } From fb3ee38dc6d504d921a32b71a969cae86121002b Mon Sep 17 00:00:00 2001 From: Art Begolli Date: Fri, 26 Jul 2019 16:06:10 +0100 Subject: [PATCH 07/12] feat(): initial json output functionality Signed-off-by: Art Begolli --- cmd/helm/search.go | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/cmd/helm/search.go b/cmd/helm/search.go index 99ffafbd3..79ff91f97 100644 --- a/cmd/helm/search.go +++ b/cmd/helm/search.go @@ -17,6 +17,7 @@ limitations under the License. package main import ( + "encoding/json" "fmt" "io" "strings" @@ -48,6 +49,14 @@ type searchCmd struct { regexp bool version string colWidth uint + output string +} + +type ResultEntry struct { + Name string `json:"name"` + ChartVersion string `json:"chartVersion"` + AppVersion string `json:"appVersion"` + Description string `json:"description"` } func newSearchCmd(out io.Writer) *cobra.Command { @@ -68,6 +77,7 @@ func newSearchCmd(out io.Writer) *cobra.Command { f.BoolVarP(&sc.versions, "versions", "l", false, "Show the long listing, with each version of each chart on its own line") f.StringVarP(&sc.version, "version", "v", "", "Search using semantic versioning constraints") f.UintVar(&sc.colWidth, "col-width", 60, "Specifies the max column width of output") + f.StringVarP(&sc.output, "output", "o", "", "Show the output in specified format") return cmd } @@ -95,6 +105,12 @@ func (s *searchCmd) run(args []string) error { return err } + if s.output == "json" { + formattedResults, _ := s.formatSearchResultsJson(data, s.colWidth) + fmt.Fprintln(s.out, formattedResults) + return nil + } + fmt.Fprintln(s.out, s.formatSearchResults(data, s.colWidth)) return nil @@ -141,6 +157,28 @@ func (s *searchCmd) formatSearchResults(res []*search.Result, colWidth uint) str return table.String() } +func (s *searchCmd) formatSearchResultsJson(res []*search.Result, colWidth uint) (string, error) { + if len(res) == 0 { + return "No results found", nil + } + resultJson := []ResultEntry{} + for _, r := range res { + resultRow := ResultEntry{ + Name: r.Name, + ChartVersion: r.Chart.Version, + AppVersion: r.Chart.AppVersion, + Description: r.Chart.Description, + } + resultJson = append(resultJson, resultRow) + } + json, err := json.MarshalIndent(resultJson, "", " ") + if err != nil { + return "", err + } + + return string(json), nil +} + func (s *searchCmd) buildIndex() (*search.Index, error) { // Load the repositories.yaml rf, err := repo.LoadRepositoriesFile(s.helmhome.RepositoryFile()) From 5b90613fc208fe841aa6eceb4b57f9a55123af16 Mon Sep 17 00:00:00 2001 From: Art Begolli Date: Fri, 26 Jul 2019 17:49:07 +0100 Subject: [PATCH 08/12] feat(): adding unit test for json flag Signed-off-by: Art Begolli --- cmd/helm/search_test.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cmd/helm/search_test.go b/cmd/helm/search_test.go index 233f94572..6a1e84f24 100644 --- a/cmd/helm/search_test.go +++ b/cmd/helm/search_test.go @@ -84,6 +84,12 @@ func TestSearchCmd(t *testing.T) { flags: []string{"--regexp"}, err: true, }, + { + name: "search for 'alpine', expect two matches in json", + args: []string{"alpine"}, + flags: []string{"--output", "json"}, + expected: "[\n {\n \"name\": \"testing/alpine\",\n \"chartVersion\": \"0.2.0\",\n \"appVersion\": \"2.3.4\",\n \"description\": \"Deploy a basic Alpine Linux pod\"\n }\n]\n", + }, } cleanup := resetEnv() From da891450b960a677a64a1df51d9a4f226e80eb12 Mon Sep 17 00:00:00 2001 From: Art Begolli Date: Fri, 26 Jul 2019 17:57:19 +0100 Subject: [PATCH 09/12] feat(): updating array to json Signed-off-by: Art Begolli --- cmd/helm/search.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cmd/helm/search.go b/cmd/helm/search.go index 79ff91f97..1a136cb2f 100644 --- a/cmd/helm/search.go +++ b/cmd/helm/search.go @@ -59,6 +59,10 @@ type ResultEntry struct { Description string `json:"description"` } +type Results struct { + SearchResults []ResultEntry `json:"searchResults"` +} + func newSearchCmd(out io.Writer) *cobra.Command { sc := &searchCmd{out: out} @@ -171,7 +175,7 @@ func (s *searchCmd) formatSearchResultsJson(res []*search.Result, colWidth uint) } resultJson = append(resultJson, resultRow) } - json, err := json.MarshalIndent(resultJson, "", " ") + json, err := json.MarshalIndent(Results{SearchResults: resultJson}, "", " ") if err != nil { return "", err } From 9672000bfb7cf239c74a0525c889f4ff59470958 Mon Sep 17 00:00:00 2001 From: Art Begolli Date: Sat, 27 Jul 2019 17:51:09 +0100 Subject: [PATCH 10/12] feat(): adding error handling --- cmd/helm/search.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cmd/helm/search.go b/cmd/helm/search.go index 1a136cb2f..7db476b3a 100644 --- a/cmd/helm/search.go +++ b/cmd/helm/search.go @@ -110,7 +110,11 @@ func (s *searchCmd) run(args []string) error { } if s.output == "json" { - formattedResults, _ := s.formatSearchResultsJson(data, s.colWidth) + formattedResults, err := s.formatSearchResultsJson(data, s.colWidth) + if err != nil { + return err + } + fmt.Fprintln(s.out, formattedResults) return nil } From bdbc88215c4ead2d8583d671be3bc76bf2d3ff66 Mon Sep 17 00:00:00 2001 From: Art Begolli Date: Sun, 11 Aug 2019 20:52:52 +0100 Subject: [PATCH 11/12] feat(): fix failing test --- cmd/helm/search.go | 8 +++++--- cmd/helm/search_test.go | 8 ++++---- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/cmd/helm/search.go b/cmd/helm/search.go index 7db476b3a..631f39140 100644 --- a/cmd/helm/search.go +++ b/cmd/helm/search.go @@ -166,10 +166,12 @@ func (s *searchCmd) formatSearchResults(res []*search.Result, colWidth uint) str } func (s *searchCmd) formatSearchResultsJson(res []*search.Result, colWidth uint) (string, error) { + var resultJson []ResultEntry + if len(res) == 0 { return "No results found", nil } - resultJson := []ResultEntry{} + for _, r := range res { resultRow := ResultEntry{ Name: r.Name, @@ -179,12 +181,12 @@ func (s *searchCmd) formatSearchResultsJson(res []*search.Result, colWidth uint) } resultJson = append(resultJson, resultRow) } - json, err := json.MarshalIndent(Results{SearchResults: resultJson}, "", " ") + jsonSearchResults, err := json.MarshalIndent(Results{SearchResults: resultJson}, "", " ") if err != nil { return "", err } - return string(json), nil + return string(jsonSearchResults), nil } func (s *searchCmd) buildIndex() (*search.Index, error) { diff --git a/cmd/helm/search_test.go b/cmd/helm/search_test.go index 6a1e84f24..4617ea151 100644 --- a/cmd/helm/search_test.go +++ b/cmd/helm/search_test.go @@ -85,10 +85,10 @@ func TestSearchCmd(t *testing.T) { err: true, }, { - name: "search for 'alpine', expect two matches in json", - args: []string{"alpine"}, - flags: []string{"--output", "json"}, - expected: "[\n {\n \"name\": \"testing/alpine\",\n \"chartVersion\": \"0.2.0\",\n \"appVersion\": \"2.3.4\",\n \"description\": \"Deploy a basic Alpine Linux pod\"\n }\n]\n", + name: "search for 'alpine', expect two matches in json", + args: []string{"alpine"}, + flags: []string{"--output", "json"}, + expected: "{\n \"searchResults\": \\[\n {\n \"name\": \"testing/alpine\",\n \"chartVersion\": \"0.2.0\",\n \"appVersion\": \"2.3.4\",\n \"description\": \"Deploy a basic Alpine Linux pod\"\n }\n \\]\n}", }, } From edf38f8e889ce42ac1b8407c561d18aa3ed571f2 Mon Sep 17 00:00:00 2001 From: Art Begolli Date: Sun, 11 Aug 2019 21:03:03 +0100 Subject: [PATCH 12/12] chore(): fix linting issues --- cmd/helm/search.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/cmd/helm/search.go b/cmd/helm/search.go index 631f39140..5deab0a7c 100644 --- a/cmd/helm/search.go +++ b/cmd/helm/search.go @@ -52,15 +52,15 @@ type searchCmd struct { output string } -type ResultEntry struct { +type resultEntry struct { Name string `json:"name"` ChartVersion string `json:"chartVersion"` AppVersion string `json:"appVersion"` Description string `json:"description"` } -type Results struct { - SearchResults []ResultEntry `json:"searchResults"` +type results struct { + SearchResults []resultEntry `json:"searchResults"` } func newSearchCmd(out io.Writer) *cobra.Command { @@ -110,7 +110,7 @@ func (s *searchCmd) run(args []string) error { } if s.output == "json" { - formattedResults, err := s.formatSearchResultsJson(data, s.colWidth) + formattedResults, err := s.formatSearchResultsJSON(data, s.colWidth) if err != nil { return err } @@ -165,23 +165,23 @@ func (s *searchCmd) formatSearchResults(res []*search.Result, colWidth uint) str return table.String() } -func (s *searchCmd) formatSearchResultsJson(res []*search.Result, colWidth uint) (string, error) { - var resultJson []ResultEntry +func (s *searchCmd) formatSearchResultsJSON(res []*search.Result, colWidth uint) (string, error) { + var resultJSON []resultEntry if len(res) == 0 { return "No results found", nil } for _, r := range res { - resultRow := ResultEntry{ + resultRow := resultEntry{ Name: r.Name, ChartVersion: r.Chart.Version, AppVersion: r.Chart.AppVersion, Description: r.Chart.Description, } - resultJson = append(resultJson, resultRow) + resultJSON = append(resultJSON, resultRow) } - jsonSearchResults, err := json.MarshalIndent(Results{SearchResults: resultJson}, "", " ") + jsonSearchResults, err := json.MarshalIndent(results{SearchResults: resultJSON}, "", " ") if err != nil { return "", err }