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 <youyongsong@gmail.com>
pull/9564/head
youyongsong 5 years ago committed by Chen Winston
parent a499b4b179
commit f171c33dc7

@ -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 { func newChartPullCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
return &cobra.Command{ var insecureOpt, plainHTTPOpt bool
cmd := &cobra.Command{
Use: "pull [ref]", Use: "pull [ref]",
Short: "pull a chart from remote", Short: "pull a chart from remote",
Long: chartPullDesc, Long: chartPullDesc,
@ -40,7 +41,13 @@ func newChartPullCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
Hidden: !FeatureGateOCI.IsEnabled(), Hidden: !FeatureGateOCI.IsEnabled(),
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
ref := args[0] 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
} }

@ -34,7 +34,8 @@ Must first run "helm chart save" or "helm chart pull".
` `
func newChartPushCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { func newChartPushCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
return &cobra.Command{ var insecureOpt, plainHTTPOpt bool
cmd := &cobra.Command{
Use: "push [ref]", Use: "push [ref]",
Short: "push a chart to remote", Short: "push a chart to remote",
Long: chartPushDesc, Long: chartPushDesc,
@ -42,7 +43,13 @@ func newChartPushCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
Hidden: !FeatureGateOCI.IsEnabled(), Hidden: !FeatureGateOCI.IsEnabled(),
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
ref := args[0] 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
} }

@ -19,12 +19,14 @@ package registry // import "helm.sh/helm/v3/internal/experimental/registry"
import ( import (
"bytes" "bytes"
"context" "context"
"crypto/tls"
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"sort" "sort"
"github.com/containerd/containerd/remotes"
auth "github.com/deislabs/oras/pkg/auth/docker" auth "github.com/deislabs/oras/pkg/auth/docker"
"github.com/deislabs/oras/pkg/content" "github.com/deislabs/oras/pkg/content"
"github.com/deislabs/oras/pkg/oras" "github.com/deislabs/oras/pkg/oras"
@ -76,7 +78,7 @@ func NewClient(opts ...ClientOption) (*Client, error) {
} }
} }
if client.resolver == nil { if client.resolver == nil {
resolver, err := client.authorizer.Resolver(context.Background(), http.DefaultClient, false) resolver, err := client.newResolver(false, false)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -119,7 +121,17 @@ func (c *Client) Logout(hostname string) error {
} }
// PushChart uploads a chart to a registry // 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) r, err := c.cache.FetchReference(ref)
if err != nil { if err != nil {
return err 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. // 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. // 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. // 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 == "" { if ref.Tag == "" {
return errors.New("tag explicitly required") return errors.New("tag explicitly required")
} }
@ -334,3 +356,17 @@ func (c *Client) getChartTableRows() ([][]interface{}, error) {
} }
return rows, nil 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
}

@ -186,13 +186,13 @@ func (suite *RegistryClientTestSuite) Test_3_PushChart() {
// non-existent ref // non-existent ref
ref, err := ParseReference(fmt.Sprintf("%s/testrepo/whodis:9.9.9", suite.DockerRegistryHost)) ref, err := ParseReference(fmt.Sprintf("%s/testrepo/whodis:9.9.9", suite.DockerRegistryHost))
suite.Nil(err) suite.Nil(err)
err = suite.RegistryClient.PushChart(ref) err = suite.RegistryClient.PushChart(ref, false, false)
suite.NotNil(err) suite.NotNil(err)
// existing ref // existing ref
ref, err = ParseReference(fmt.Sprintf("%s/testrepo/testchart:1.2.3", suite.DockerRegistryHost)) ref, err = ParseReference(fmt.Sprintf("%s/testrepo/testchart:1.2.3", suite.DockerRegistryHost))
suite.Nil(err) suite.Nil(err)
err = suite.RegistryClient.PushChart(ref) err = suite.RegistryClient.PushChart(ref, false, false)
suite.Nil(err) suite.Nil(err)
} }

@ -35,10 +35,10 @@ func NewChartPull(cfg *Configuration) *ChartPull {
} }
// Run executes the chart pull operation // 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) r, err := registry.ParseReference(ref)
if err != nil { if err != nil {
return err return err
} }
return a.cfg.RegistryClient.PullChartToCache(r) return a.cfg.RegistryClient.PullChartToCache(r, insecure, plainHTTP)
} }

@ -35,10 +35,10 @@ func NewChartPush(cfg *Configuration) *ChartPush {
} }
// Run executes the chart push operation // 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) r, err := registry.ParseReference(ref)
if err != nil { if err != nil {
return err return err
} }
return a.cfg.RegistryClient.PushChart(r) return a.cfg.RegistryClient.PushChart(r, insecure, plainHTTP)
} }

Loading…
Cancel
Save