From 6cb14781c4ff793aef0dcc58f511ab5e46f99641 Mon Sep 17 00:00:00 2001 From: pytimer Date: Mon, 29 Nov 2021 16:53:43 +0800 Subject: [PATCH] Push to insecure OCI registry Signed-off-by: pytimer --- cmd/helm/pull.go | 1 + cmd/helm/push.go | 4 ++++ pkg/action/pull.go | 7 +++++++ pkg/action/push.go | 12 ++++++++++-- pkg/registry/client.go | 31 +++++++++++++++++++++++++++++++ 5 files changed, 53 insertions(+), 2 deletions(-) diff --git a/cmd/helm/pull.go b/cmd/helm/pull.go index b1c04fe0a..51d679ae6 100644 --- a/cmd/helm/pull.go +++ b/cmd/helm/pull.go @@ -81,6 +81,7 @@ func newPullCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { f.BoolVar(&client.VerifyLater, "prov", false, "fetch the provenance file, but don't perform verification") f.StringVar(&client.UntarDir, "untardir", ".", "if untar is specified, this flag specifies the name of the directory into which the chart is expanded") f.StringVarP(&client.DestDir, "destination", "d", ".", "location to write the chart. If this and tardir are specified, tardir is appended to this") + f.BoolVar(&client.PlainHTTP, "plain-http", false, "use plain http and not https to connect oci registry") addChartPathOptionsFlags(f, &client.ChartPathOptions) err := cmd.RegisterFlagCompletionFunc("version", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { diff --git a/cmd/helm/push.go b/cmd/helm/push.go index ed5d1699a..e2add5088 100644 --- a/cmd/helm/push.go +++ b/cmd/helm/push.go @@ -54,5 +54,9 @@ func newPushCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { }, } + f := cmd.Flags() + f.BoolVar(&client.InsecureSkipTLSverify, "insecure-skip-tls-verify", false, "skip tls certificate checks for the chart upload") + f.BoolVar(&client.PlainHTTP, "plain-http", false, "use plain http and not https to connect oci registry") + return cmd } diff --git a/pkg/action/pull.go b/pkg/action/pull.go index b4018869e..d638527a4 100644 --- a/pkg/action/pull.go +++ b/pkg/action/pull.go @@ -46,6 +46,7 @@ type Pull struct { VerifyLater bool UntarDir string DestDir string + PlainHTTP bool cfg *Configuration } @@ -76,6 +77,12 @@ func NewPullWithOpts(opts ...PullOpt) *Pull { func (p *Pull) Run(chartRef string) (string, error) { var out strings.Builder + if p.InsecureSkipTLSverify || p.PlainHTTP { + if err := p.cfg.RegistryClient.WithResolver(p.InsecureSkipTLSverify, p.PlainHTTP); err != nil { + return out.String(), err + } + } + c := downloader.ChartDownloader{ Out: &out, Keyring: p.Keyring, diff --git a/pkg/action/push.go b/pkg/action/push.go index 99d1beadc..692b34041 100644 --- a/pkg/action/push.go +++ b/pkg/action/push.go @@ -29,8 +29,10 @@ import ( // // It provides the implementation of 'helm push'. type Push struct { - Settings *cli.EnvSettings - cfg *Configuration + Settings *cli.EnvSettings + cfg *Configuration + InsecureSkipTLSverify bool + PlainHTTP bool } // PushOpt is a type of function that sets options for a push action. @@ -56,6 +58,12 @@ func NewPushWithOpts(opts ...PushOpt) *Push { func (p *Push) Run(chartRef string, remote string) (string, error) { var out strings.Builder + if p.InsecureSkipTLSverify || p.PlainHTTP { + if err := p.cfg.RegistryClient.WithResolver(p.InsecureSkipTLSverify, p.PlainHTTP); err != nil { + return out.String(), err + } + } + c := uploader.ChartUploader{ Out: &out, Pushers: pusher.All(p.Settings), diff --git a/pkg/registry/client.go b/pkg/registry/client.go index 213a9dc49..fcde39de1 100644 --- a/pkg/registry/client.go +++ b/pkg/registry/client.go @@ -18,6 +18,7 @@ package registry // import "helm.sh/helm/v3/pkg/registry" import ( "context" + "crypto/tls" "encoding/json" "fmt" "io" @@ -145,6 +146,36 @@ func ClientOptCredentialsFile(credentialsFile string) ClientOption { } } +func (c *Client) newResolver(insecure, plainHTTP bool) (remotes.Resolver, error) { + headers := http.Header{} + headers.Set("User-Agent", version.GetUserAgent()) + opts := []auth.ResolverOption{auth.WithResolverHeaders(headers)} + + if insecure { + httpClient := http.DefaultClient + httpClient.Transport = &http.Transport{ + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: true, + }, + } + opts = append(opts, auth.WithResolverClient(httpClient)) + } + if plainHTTP { + opts = append(opts, auth.WithResolverPlainHTTP()) + } + + return c.authorizer.ResolverWithOpts(opts...) +} + +func (c *Client) WithResolver(insecure, plainHTTP bool) error { + resolver, err := c.newResolver(insecure, plainHTTP) + if err != nil { + return err + } + c.resolver = resolver + return nil +} + type ( // LoginOption allows specifying various settings on login LoginOption func(*loginOperation)