From f171c33dc7e858ca9f1c8c0332fc6b70256edd48 Mon Sep 17 00:00:00 2001 From: youyongsong Date: Fri, 17 Jul 2020 15:17:28 +0800 Subject: [PATCH] support insecure and plain-http options in helm chart pull and push commands This pr tries to resolve issue #8464 and #6324. helm only support `--insecure` option in the helm registry login command. In some cases we want to push or pull a chart to a insecure or http registry anonymously without login, so I add `--insecure` and `--plain-http` options to meet these cases. Signed-off-by: youyongsong --- cmd/helm/chart_pull.go | 11 ++++- cmd/helm/chart_push.go | 11 ++++- internal/experimental/registry/client.go | 42 +++++++++++++++++-- internal/experimental/registry/client_test.go | 4 +- pkg/action/chart_pull.go | 4 +- pkg/action/chart_push.go | 4 +- 6 files changed, 63 insertions(+), 13 deletions(-) diff --git a/cmd/helm/chart_pull.go b/cmd/helm/chart_pull.go index 760ff3e2c..5c18dc3e3 100644 --- a/cmd/helm/chart_pull.go +++ b/cmd/helm/chart_pull.go @@ -32,7 +32,8 @@ This will store the chart in the local registry cache to be used later. ` func newChartPullCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { - return &cobra.Command{ + var insecureOpt, plainHTTPOpt bool + cmd := &cobra.Command{ Use: "pull [ref]", Short: "pull a chart from remote", Long: chartPullDesc, @@ -40,7 +41,13 @@ func newChartPullCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { Hidden: !FeatureGateOCI.IsEnabled(), RunE: func(cmd *cobra.Command, args []string) error { ref := args[0] - return action.NewChartPull(cfg).Run(out, ref) + return action.NewChartPull(cfg).Run(out, ref, insecureOpt, plainHTTPOpt) }, } + + f := cmd.Flags() + f.BoolVarP(&insecureOpt, "insecure", "", false, "allow connections to TLS registry without certs") + f.BoolVarP(&plainHTTPOpt, "plain-http", "", false, "use plain http and not https") + + return cmd } diff --git a/cmd/helm/chart_push.go b/cmd/helm/chart_push.go index ff34632b1..9f70b579d 100644 --- a/cmd/helm/chart_push.go +++ b/cmd/helm/chart_push.go @@ -34,7 +34,8 @@ Must first run "helm chart save" or "helm chart pull". ` func newChartPushCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { - return &cobra.Command{ + var insecureOpt, plainHTTPOpt bool + cmd := &cobra.Command{ Use: "push [ref]", Short: "push a chart to remote", Long: chartPushDesc, @@ -42,7 +43,13 @@ func newChartPushCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { Hidden: !FeatureGateOCI.IsEnabled(), RunE: func(cmd *cobra.Command, args []string) error { ref := args[0] - return action.NewChartPush(cfg).Run(out, ref) + return action.NewChartPush(cfg).Run(out, ref, insecureOpt, plainHTTPOpt) }, } + + f := cmd.Flags() + f.BoolVarP(&insecureOpt, "insecure", "", false, "allow connections to TLS registry without certs") + f.BoolVarP(&plainHTTPOpt, "plain-http", "", false, "use plain http and not https") + + return cmd } diff --git a/internal/experimental/registry/client.go b/internal/experimental/registry/client.go index c889ee913..e2dbf6ddf 100644 --- a/internal/experimental/registry/client.go +++ b/internal/experimental/registry/client.go @@ -19,12 +19,14 @@ package registry // import "helm.sh/helm/v3/internal/experimental/registry" import ( "bytes" "context" + "crypto/tls" "fmt" "io" "io/ioutil" "net/http" "sort" + "github.com/containerd/containerd/remotes" auth "github.com/deislabs/oras/pkg/auth/docker" "github.com/deislabs/oras/pkg/content" "github.com/deislabs/oras/pkg/oras" @@ -76,7 +78,7 @@ func NewClient(opts ...ClientOption) (*Client, error) { } } if client.resolver == nil { - resolver, err := client.authorizer.Resolver(context.Background(), http.DefaultClient, false) + resolver, err := client.newResolver(false, false) if err != nil { return nil, err } @@ -119,7 +121,17 @@ func (c *Client) Logout(hostname string) error { } // PushChart uploads a chart to a registry -func (c *Client) PushChart(ref *Reference) error { +func (c *Client) PushChart(ref *Reference, insecure bool, plainHTTP bool) error { + if insecure || plainHTTP { + resolver, err := c.newResolver(insecure, plainHTTP) + if err != nil { + return err + } + c.resolver = &Resolver{ + Resolver: resolver, + } + } + r, err := c.cache.FetchReference(ref) if err != nil { return err @@ -199,7 +211,17 @@ func (c *Client) PullChart(ref *Reference) (*bytes.Buffer, error) { // PullChartToCache pulls a chart from an OCI Registry to the Registry Cache. // This function is needed for `helm chart pull`, which is experimental and will be deprecated soon. // Likewise, the Registry cache will soon be deprecated as will this function. -func (c *Client) PullChartToCache(ref *Reference) error { +func (c *Client) PullChartToCache(ref *Reference, insecure bool, plainHTTP bool) error { + if insecure || plainHTTP { + resolver, err := c.newResolver(insecure, plainHTTP) + if err != nil { + return err + } + c.resolver = &Resolver{ + Resolver: resolver, + } + } + if ref.Tag == "" { return errors.New("tag explicitly required") } @@ -334,3 +356,17 @@ func (c *Client) getChartTableRows() ([][]interface{}, error) { } return rows, nil } + +func (c *Client) newResolver(insecure bool, plainHTTP bool) (resolver remotes.Resolver, err error) { + client := http.DefaultClient + if insecure { + client.Transport = &http.Transport{ + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: true, + }, + } + } + + resolver, err = c.authorizer.Resolver(context.Background(), client, plainHTTP) + return +} diff --git a/internal/experimental/registry/client_test.go b/internal/experimental/registry/client_test.go index a9936ba13..96aa2edc5 100644 --- a/internal/experimental/registry/client_test.go +++ b/internal/experimental/registry/client_test.go @@ -186,13 +186,13 @@ func (suite *RegistryClientTestSuite) Test_3_PushChart() { // non-existent ref ref, err := ParseReference(fmt.Sprintf("%s/testrepo/whodis:9.9.9", suite.DockerRegistryHost)) suite.Nil(err) - err = suite.RegistryClient.PushChart(ref) + err = suite.RegistryClient.PushChart(ref, false, false) suite.NotNil(err) // existing ref ref, err = ParseReference(fmt.Sprintf("%s/testrepo/testchart:1.2.3", suite.DockerRegistryHost)) suite.Nil(err) - err = suite.RegistryClient.PushChart(ref) + err = suite.RegistryClient.PushChart(ref, false, false) suite.Nil(err) } diff --git a/pkg/action/chart_pull.go b/pkg/action/chart_pull.go index 896755201..a446c49d2 100644 --- a/pkg/action/chart_pull.go +++ b/pkg/action/chart_pull.go @@ -35,10 +35,10 @@ func NewChartPull(cfg *Configuration) *ChartPull { } // Run executes the chart pull operation -func (a *ChartPull) Run(out io.Writer, ref string) error { +func (a *ChartPull) Run(out io.Writer, ref string, insecure bool, plainHTTP bool) error { r, err := registry.ParseReference(ref) if err != nil { return err } - return a.cfg.RegistryClient.PullChartToCache(r) + return a.cfg.RegistryClient.PullChartToCache(r, insecure, plainHTTP) } diff --git a/pkg/action/chart_push.go b/pkg/action/chart_push.go index 91ec49d38..707d6a59b 100644 --- a/pkg/action/chart_push.go +++ b/pkg/action/chart_push.go @@ -35,10 +35,10 @@ func NewChartPush(cfg *Configuration) *ChartPush { } // Run executes the chart push operation -func (a *ChartPush) Run(out io.Writer, ref string) error { +func (a *ChartPush) Run(out io.Writer, ref string, insecure bool, plainHTTP bool) error { r, err := registry.ParseReference(ref) if err != nil { return err } - return a.cfg.RegistryClient.PushChart(r) + return a.cfg.RegistryClient.PushChart(r, insecure, plainHTTP) }