Merge pull request from banjoh/em/password-to-oci-registries

fix(helm): pass down username/password CLI parameters to OCI registry clients
dependabot/go_modules/github.com/Masterminds/semver/v3-3.3.1
Scott Rigby 4 months ago committed by GitHub
commit bca7d31c9b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -20,6 +20,7 @@ import (
"path/filepath" "path/filepath"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/pflag"
"helm.sh/helm/v3/cmd/helm/require" "helm.sh/helm/v3/cmd/helm/require"
"helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/action"
@ -93,7 +94,7 @@ func newDependencyCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
cmd.AddCommand(newDependencyListCmd(out)) cmd.AddCommand(newDependencyListCmd(out))
cmd.AddCommand(newDependencyUpdateCmd(cfg, out)) cmd.AddCommand(newDependencyUpdateCmd(cfg, out))
cmd.AddCommand(newDependencyBuildCmd(cfg, out)) cmd.AddCommand(newDependencyBuildCmd(out))
return cmd return cmd
} }
@ -120,3 +121,16 @@ func newDependencyListCmd(out io.Writer) *cobra.Command {
f.UintVar(&client.ColumnWidth, "max-col-width", 80, "maximum column width for output table") f.UintVar(&client.ColumnWidth, "max-col-width", 80, "maximum column width for output table")
return cmd return cmd
} }
func addDependencySubcommandFlags(f *pflag.FlagSet, client *action.Dependency) {
f.BoolVar(&client.Verify, "verify", false, "verify the packages against signatures")
f.StringVar(&client.Keyring, "keyring", defaultKeyring(), "keyring containing public keys")
f.BoolVar(&client.SkipRefresh, "skip-refresh", false, "do not refresh the local repository cache")
f.StringVar(&client.Username, "username", "", "chart repository username where to locate the requested chart")
f.StringVar(&client.Password, "password", "", "chart repository password where to locate the requested chart")
f.StringVar(&client.CertFile, "cert-file", "", "identify HTTPS client using this SSL certificate file")
f.StringVar(&client.KeyFile, "key-file", "", "identify HTTPS client using this SSL key file")
f.BoolVar(&client.InsecureSkipTLSverify, "insecure-skip-tls-verify", false, "skip tls certificate checks for the chart download")
f.BoolVar(&client.PlainHTTP, "plain-http", false, "use insecure HTTP connections for the chart download")
f.StringVar(&client.CaFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle")
}

@ -41,7 +41,7 @@ If no lock file is found, 'helm dependency build' will mirror the behavior
of 'helm dependency update'. of 'helm dependency update'.
` `
func newDependencyBuildCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { func newDependencyBuildCmd(out io.Writer) *cobra.Command {
client := action.NewDependency() client := action.NewDependency()
cmd := &cobra.Command{ cmd := &cobra.Command{
@ -54,13 +54,19 @@ func newDependencyBuildCmd(cfg *action.Configuration, out io.Writer) *cobra.Comm
if len(args) > 0 { if len(args) > 0 {
chartpath = filepath.Clean(args[0]) chartpath = filepath.Clean(args[0])
} }
registryClient, err := newRegistryClient(client.CertFile, client.KeyFile, client.CaFile,
client.InsecureSkipTLSverify, client.PlainHTTP, client.Username, client.Password)
if err != nil {
return fmt.Errorf("missing registry client: %w", err)
}
man := &downloader.Manager{ man := &downloader.Manager{
Out: out, Out: out,
ChartPath: chartpath, ChartPath: chartpath,
Keyring: client.Keyring, Keyring: client.Keyring,
SkipUpdate: client.SkipRefresh, SkipUpdate: client.SkipRefresh,
Getters: getter.All(settings), Getters: getter.All(settings),
RegistryClient: cfg.RegistryClient, RegistryClient: registryClient,
RepositoryConfig: settings.RepositoryConfig, RepositoryConfig: settings.RepositoryConfig,
RepositoryCache: settings.RepositoryCache, RepositoryCache: settings.RepositoryCache,
Debug: settings.Debug, Debug: settings.Debug,
@ -68,7 +74,7 @@ func newDependencyBuildCmd(cfg *action.Configuration, out io.Writer) *cobra.Comm
if client.Verify { if client.Verify {
man.Verify = downloader.VerifyIfPossible man.Verify = downloader.VerifyIfPossible
} }
err := man.Build() err = man.Build()
if e, ok := err.(downloader.ErrRepoNotFound); ok { if e, ok := err.(downloader.ErrRepoNotFound); ok {
return fmt.Errorf("%s. Please add the missing repos via 'helm repo add'", e.Error()) return fmt.Errorf("%s. Please add the missing repos via 'helm repo add'", e.Error())
} }
@ -77,9 +83,7 @@ func newDependencyBuildCmd(cfg *action.Configuration, out io.Writer) *cobra.Comm
} }
f := cmd.Flags() f := cmd.Flags()
f.BoolVar(&client.Verify, "verify", false, "verify the packages against signatures") addDependencySubcommandFlags(f, client)
f.StringVar(&client.Keyring, "keyring", defaultKeyring(), "keyring containing public keys")
f.BoolVar(&client.SkipRefresh, "skip-refresh", false, "do not refresh the local repository cache")
return cmd return cmd
} }

@ -16,6 +16,7 @@ limitations under the License.
package main package main
import ( import (
"fmt"
"io" "io"
"path/filepath" "path/filepath"
@ -43,7 +44,7 @@ in the Chart.yaml file, but (b) at the wrong version.
` `
// newDependencyUpdateCmd creates a new dependency update command. // newDependencyUpdateCmd creates a new dependency update command.
func newDependencyUpdateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { func newDependencyUpdateCmd(_ *action.Configuration, out io.Writer) *cobra.Command {
client := action.NewDependency() client := action.NewDependency()
cmd := &cobra.Command{ cmd := &cobra.Command{
@ -57,13 +58,19 @@ func newDependencyUpdateCmd(cfg *action.Configuration, out io.Writer) *cobra.Com
if len(args) > 0 { if len(args) > 0 {
chartpath = filepath.Clean(args[0]) chartpath = filepath.Clean(args[0])
} }
registryClient, err := newRegistryClient(client.CertFile, client.KeyFile, client.CaFile,
client.InsecureSkipTLSverify, client.PlainHTTP, client.Username, client.Password)
if err != nil {
return fmt.Errorf("missing registry client: %w", err)
}
man := &downloader.Manager{ man := &downloader.Manager{
Out: out, Out: out,
ChartPath: chartpath, ChartPath: chartpath,
Keyring: client.Keyring, Keyring: client.Keyring,
SkipUpdate: client.SkipRefresh, SkipUpdate: client.SkipRefresh,
Getters: getter.All(settings), Getters: getter.All(settings),
RegistryClient: cfg.RegistryClient, RegistryClient: registryClient,
RepositoryConfig: settings.RepositoryConfig, RepositoryConfig: settings.RepositoryConfig,
RepositoryCache: settings.RepositoryCache, RepositoryCache: settings.RepositoryCache,
Debug: settings.Debug, Debug: settings.Debug,
@ -76,9 +83,7 @@ func newDependencyUpdateCmd(cfg *action.Configuration, out io.Writer) *cobra.Com
} }
f := cmd.Flags() f := cmd.Flags()
f.BoolVar(&client.Verify, "verify", false, "verify the packages against signatures") addDependencySubcommandFlags(f, client)
f.StringVar(&client.Keyring, "keyring", defaultKeyring(), "keyring containing public keys")
f.BoolVar(&client.SkipRefresh, "skip-refresh", false, "do not refresh the local repository cache")
return cmd return cmd
} }

@ -141,7 +141,7 @@ func newInstallCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
}, },
RunE: func(_ *cobra.Command, args []string) error { RunE: func(_ *cobra.Command, args []string) error {
registryClient, err := newRegistryClient(client.CertFile, client.KeyFile, client.CaFile, registryClient, err := newRegistryClient(client.CertFile, client.KeyFile, client.CaFile,
client.InsecureSkipTLSverify, client.PlainHTTP) client.InsecureSkipTLSverify, client.PlainHTTP, client.Username, client.Password)
if err != nil { if err != nil {
return fmt.Errorf("missing registry client: %w", err) return fmt.Errorf("missing registry client: %w", err)
} }

@ -47,7 +47,7 @@ If '--keyring' is not specified, Helm usually defaults to the public keyring
unless your environment is otherwise configured. unless your environment is otherwise configured.
` `
func newPackageCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { func newPackageCmd(out io.Writer) *cobra.Command {
client := action.NewPackage() client := action.NewPackage()
valueOpts := &values.Options{} valueOpts := &values.Options{}
@ -75,6 +75,12 @@ func newPackageCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
return err return err
} }
registryClient, err := newRegistryClient(client.CertFile, client.KeyFile, client.CaFile,
client.InsecureSkipTLSverify, client.PlainHTTP, client.Username, client.Password)
if err != nil {
return fmt.Errorf("missing registry client: %w", err)
}
for i := 0; i < len(args); i++ { for i := 0; i < len(args); i++ {
path, err := filepath.Abs(args[i]) path, err := filepath.Abs(args[i])
if err != nil { if err != nil {
@ -91,7 +97,7 @@ func newPackageCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
Keyring: client.Keyring, Keyring: client.Keyring,
Getters: p, Getters: p,
Debug: settings.Debug, Debug: settings.Debug,
RegistryClient: cfg.RegistryClient, RegistryClient: registryClient,
RepositoryConfig: settings.RepositoryConfig, RepositoryConfig: settings.RepositoryConfig,
RepositoryCache: settings.RepositoryCache, RepositoryCache: settings.RepositoryCache,
} }
@ -119,6 +125,13 @@ func newPackageCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
f.StringVar(&client.AppVersion, "app-version", "", "set the appVersion on the chart to this version") f.StringVar(&client.AppVersion, "app-version", "", "set the appVersion on the chart to this version")
f.StringVarP(&client.Destination, "destination", "d", ".", "location to write the chart.") f.StringVarP(&client.Destination, "destination", "d", ".", "location to write the chart.")
f.BoolVarP(&client.DependencyUpdate, "dependency-update", "u", false, `update dependencies from "Chart.yaml" to dir "charts/" before packaging`) f.BoolVarP(&client.DependencyUpdate, "dependency-update", "u", false, `update dependencies from "Chart.yaml" to dir "charts/" before packaging`)
f.StringVar(&client.Username, "username", "", "chart repository username where to locate the requested chart")
f.StringVar(&client.Password, "password", "", "chart repository password where to locate the requested chart")
f.StringVar(&client.CertFile, "cert-file", "", "identify HTTPS client using this SSL certificate file")
f.StringVar(&client.KeyFile, "key-file", "", "identify HTTPS client using this SSL key file")
f.BoolVar(&client.InsecureSkipTLSverify, "insecure-skip-tls-verify", false, "skip tls certificate checks for the chart download")
f.BoolVar(&client.PlainHTTP, "plain-http", false, "use insecure HTTP connections for the chart download")
f.StringVar(&client.CaFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle")
return cmd return cmd
} }

@ -65,7 +65,7 @@ func newPullCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
} }
registryClient, err := newRegistryClient(client.CertFile, client.KeyFile, client.CaFile, registryClient, err := newRegistryClient(client.CertFile, client.KeyFile, client.CaFile,
client.InsecureSkipTLSverify, client.PlainHTTP) client.InsecureSkipTLSverify, client.PlainHTTP, client.Username, client.Password)
if err != nil { if err != nil {
return fmt.Errorf("missing registry client: %w", err) return fmt.Errorf("missing registry client: %w", err)
} }

@ -40,6 +40,8 @@ type registryPushOptions struct {
caFile string caFile string
insecureSkipTLSverify bool insecureSkipTLSverify bool
plainHTTP bool plainHTTP bool
password string
username string
} }
func newPushCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { func newPushCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
@ -68,7 +70,10 @@ func newPushCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
return noMoreArgsComp() return noMoreArgsComp()
}, },
RunE: func(_ *cobra.Command, args []string) error { RunE: func(_ *cobra.Command, args []string) error {
registryClient, err := newRegistryClient(o.certFile, o.keyFile, o.caFile, o.insecureSkipTLSverify, o.plainHTTP) registryClient, err := newRegistryClient(
o.certFile, o.keyFile, o.caFile, o.insecureSkipTLSverify, o.plainHTTP, o.username, o.password,
)
if err != nil { if err != nil {
return fmt.Errorf("missing registry client: %w", err) return fmt.Errorf("missing registry client: %w", err)
} }
@ -96,6 +101,8 @@ func newPushCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
f.StringVar(&o.caFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle") f.StringVar(&o.caFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle")
f.BoolVar(&o.insecureSkipTLSverify, "insecure-skip-tls-verify", false, "skip tls certificate checks for the chart upload") f.BoolVar(&o.insecureSkipTLSverify, "insecure-skip-tls-verify", false, "skip tls certificate checks for the chart upload")
f.BoolVar(&o.plainHTTP, "plain-http", false, "use insecure HTTP connections for the chart upload") f.BoolVar(&o.plainHTTP, "plain-http", false, "use insecure HTTP connections for the chart upload")
f.StringVar(&o.username, "username", "", "chart repository username where to locate the requested chart")
f.StringVar(&o.password, "password", "", "chart repository password where to locate the requested chart")
return cmd return cmd
} }

@ -21,6 +21,7 @@ import (
"fmt" "fmt"
"io" "io"
"log" "log"
"net/http"
"os" "os"
"strings" "strings"
@ -29,6 +30,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/tools/clientcmd"
"helm.sh/helm/v3/internal/tlsutil"
"helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/registry" "helm.sh/helm/v3/pkg/registry"
"helm.sh/helm/v3/pkg/repo" "helm.sh/helm/v3/pkg/repo"
@ -153,7 +155,7 @@ func newRootCmd(actionConfig *action.Configuration, out io.Writer, args []string
flags.ParseErrorsWhitelist.UnknownFlags = true flags.ParseErrorsWhitelist.UnknownFlags = true
flags.Parse(args) flags.Parse(args)
registryClient, err := newDefaultRegistryClient(false) registryClient, err := newDefaultRegistryClient(false, "", "")
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -167,7 +169,7 @@ func newRootCmd(actionConfig *action.Configuration, out io.Writer, args []string
newPullCmd(actionConfig, out), newPullCmd(actionConfig, out),
newShowCmd(actionConfig, out), newShowCmd(actionConfig, out),
newLintCmd(out), newLintCmd(out),
newPackageCmd(actionConfig, out), newPackageCmd(out),
newRepoCmd(out), newRepoCmd(out),
newSearchCmd(out), newSearchCmd(out),
newVerifyCmd(out), newVerifyCmd(out),
@ -255,27 +257,30 @@ func checkForExpiredRepos(repofile string) {
} }
func newRegistryClient(certFile, keyFile, caFile string, insecureSkipTLSverify, plainHTTP bool) (*registry.Client, error) { func newRegistryClient(
certFile, keyFile, caFile string, insecureSkipTLSverify, plainHTTP bool, username, password string,
) (*registry.Client, error) {
if certFile != "" && keyFile != "" || caFile != "" || insecureSkipTLSverify { if certFile != "" && keyFile != "" || caFile != "" || insecureSkipTLSverify {
registryClient, err := newRegistryClientWithTLS(certFile, keyFile, caFile, insecureSkipTLSverify) registryClient, err := newRegistryClientWithTLS(certFile, keyFile, caFile, insecureSkipTLSverify, username, password)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return registryClient, nil return registryClient, nil
} }
registryClient, err := newDefaultRegistryClient(plainHTTP) registryClient, err := newDefaultRegistryClient(plainHTTP, username, password)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return registryClient, nil return registryClient, nil
} }
func newDefaultRegistryClient(plainHTTP bool) (*registry.Client, error) { func newDefaultRegistryClient(plainHTTP bool, username, password string) (*registry.Client, error) {
opts := []registry.ClientOption{ opts := []registry.ClientOption{
registry.ClientOptDebug(settings.Debug), registry.ClientOptDebug(settings.Debug),
registry.ClientOptEnableCache(true), registry.ClientOptEnableCache(true),
registry.ClientOptWriter(os.Stderr), registry.ClientOptWriter(os.Stderr),
registry.ClientOptCredentialsFile(settings.RegistryConfig), registry.ClientOptCredentialsFile(settings.RegistryConfig),
registry.ClientOptBasicAuth(username, password),
} }
if plainHTTP { if plainHTTP {
opts = append(opts, registry.ClientOptPlainHTTP()) opts = append(opts, registry.ClientOptPlainHTTP())
@ -289,10 +294,26 @@ func newDefaultRegistryClient(plainHTTP bool) (*registry.Client, error) {
return registryClient, nil return registryClient, nil
} }
func newRegistryClientWithTLS(certFile, keyFile, caFile string, insecureSkipTLSverify bool) (*registry.Client, error) { func newRegistryClientWithTLS(
certFile, keyFile, caFile string, insecureSkipTLSverify bool, username, password string,
) (*registry.Client, error) {
tlsConf, err := tlsutil.NewClientTLS(certFile, keyFile, caFile, insecureSkipTLSverify)
if err != nil {
return nil, fmt.Errorf("can't create TLS config for client: %w", err)
}
// Create a new registry client // Create a new registry client
registryClient, err := registry.NewRegistryClientWithTLS(os.Stderr, certFile, keyFile, caFile, insecureSkipTLSverify, registryClient, err := registry.NewClient(
settings.RegistryConfig, settings.Debug, registry.ClientOptDebug(settings.Debug),
registry.ClientOptEnableCache(true),
registry.ClientOptWriter(os.Stderr),
registry.ClientOptCredentialsFile(settings.RegistryConfig),
registry.ClientOptHTTPClient(&http.Client{
Transport: &http.Transport{
TLSClientConfig: tlsConf,
},
}),
registry.ClientOptBasicAuth(username, password),
) )
if err != nil { if err != nil {
return nil, err return nil, err

@ -226,7 +226,7 @@ func runShow(args []string, client *action.Show) (string, error) {
func addRegistryClient(client *action.Show) error { func addRegistryClient(client *action.Show) error {
registryClient, err := newRegistryClient(client.CertFile, client.KeyFile, client.CaFile, registryClient, err := newRegistryClient(client.CertFile, client.KeyFile, client.CaFile,
client.InsecureSkipTLSverify, client.PlainHTTP) client.InsecureSkipTLSverify, client.PlainHTTP, client.Username, client.Password)
if err != nil { if err != nil {
return fmt.Errorf("missing registry client: %w", err) return fmt.Errorf("missing registry client: %w", err)
} }

@ -74,7 +74,7 @@ func newTemplateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
} }
registryClient, err := newRegistryClient(client.CertFile, client.KeyFile, client.CaFile, registryClient, err := newRegistryClient(client.CertFile, client.KeyFile, client.CaFile,
client.InsecureSkipTLSverify, client.PlainHTTP) client.InsecureSkipTLSverify, client.PlainHTTP, client.Username, client.Password)
if err != nil { if err != nil {
return fmt.Errorf("missing registry client: %w", err) return fmt.Errorf("missing registry client: %w", err)
} }

@ -103,7 +103,7 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
client.Namespace = settings.Namespace() client.Namespace = settings.Namespace()
registryClient, err := newRegistryClient(client.CertFile, client.KeyFile, client.CaFile, registryClient, err := newRegistryClient(client.CertFile, client.KeyFile, client.CaFile,
client.InsecureSkipTLSverify, client.PlainHTTP) client.InsecureSkipTLSverify, client.PlainHTTP, client.Username, client.Password)
if err != nil { if err != nil {
return fmt.Errorf("missing registry client: %w", err) return fmt.Errorf("missing registry client: %w", err)
} }

@ -38,6 +38,13 @@ type Dependency struct {
Keyring string Keyring string
SkipRefresh bool SkipRefresh bool
ColumnWidth uint ColumnWidth uint
Username string
Password string
CertFile string
KeyFile string
CaFile string
InsecureSkipTLSverify bool
PlainHTTP bool
} }
// NewDependency creates a new Dependency object with the given configuration. // NewDependency creates a new Dependency object with the given configuration.

@ -770,6 +770,7 @@ func (c *ChartPathOptions) LocateChart(name string, settings *cli.EnvSettings) (
getter.WithTLSClientConfig(c.CertFile, c.KeyFile, c.CaFile), getter.WithTLSClientConfig(c.CertFile, c.KeyFile, c.CaFile),
getter.WithInsecureSkipVerifyTLS(c.InsecureSkipTLSverify), getter.WithInsecureSkipVerifyTLS(c.InsecureSkipTLSverify),
getter.WithPlainHTTP(c.PlainHTTP), getter.WithPlainHTTP(c.PlainHTTP),
getter.WithBasicAuth(c.Username, c.Password),
}, },
RepositoryConfig: settings.RepositoryConfig, RepositoryConfig: settings.RepositoryConfig,
RepositoryCache: settings.RepositoryCache, RepositoryCache: settings.RepositoryCache,

@ -46,6 +46,13 @@ type Package struct {
RepositoryConfig string RepositoryConfig string
RepositoryCache string RepositoryCache string
PlainHTTP bool
Username string
Password string
CertFile string
KeyFile string
CaFile string
InsecureSkipTLSverify bool
} }
// NewPackage creates a new Package object with the given configuration. // NewPackage creates a new Package object with the given configuration.

@ -18,6 +18,7 @@ package registry // import "helm.sh/helm/v3/pkg/registry"
import ( import (
"context" "context"
"encoding/base64"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
@ -56,6 +57,8 @@ type (
enableCache bool enableCache bool
// path to repository config file e.g. ~/.docker/config.json // path to repository config file e.g. ~/.docker/config.json
credentialsFile string credentialsFile string
username string
password string
out io.Writer out io.Writer
authorizer auth.Client authorizer auth.Client
registryAuthorizer *registryauth.Client registryAuthorizer *registryauth.Client
@ -105,6 +108,19 @@ func NewClient(options ...ClientOption) (*Client, error) {
if client.plainHTTP { if client.plainHTTP {
opts = append(opts, auth.WithResolverPlainHTTP()) opts = append(opts, auth.WithResolverPlainHTTP())
} }
// if username and password are set, use them for authentication
// by adding the basic auth Authorization header to the resolver
if client.username != "" && client.password != "" {
concat := client.username + ":" + client.password
encodedAuth := base64.StdEncoding.EncodeToString([]byte(concat))
opts = append(opts, auth.WithResolverHeaders(
http.Header{
"Authorization": []string{"Basic " + encodedAuth},
},
))
}
resolver, err := client.authorizer.ResolverWithOpts(opts...) resolver, err := client.authorizer.ResolverWithOpts(opts...)
if err != nil { if err != nil {
return nil, err return nil, err
@ -125,6 +141,13 @@ func NewClient(options ...ClientOption) (*Client, error) {
}, },
Cache: cache, Cache: cache,
Credential: func(_ context.Context, reg string) (registryauth.Credential, error) { Credential: func(_ context.Context, reg string) (registryauth.Credential, error) {
if client.username != "" && client.password != "" {
return registryauth.Credential{
Username: client.username,
Password: client.password,
}, nil
}
dockerClient, ok := client.authorizer.(*dockerauth.Client) dockerClient, ok := client.authorizer.(*dockerauth.Client)
if !ok { if !ok {
return registryauth.EmptyCredential, errors.New("unable to obtain docker client") return registryauth.EmptyCredential, errors.New("unable to obtain docker client")
@ -168,6 +191,14 @@ func ClientOptEnableCache(enableCache bool) ClientOption {
} }
} }
// ClientOptBasicAuth returns a function that sets the username and password setting on client options set
func ClientOptBasicAuth(username, password string) ClientOption {
return func(client *Client) {
client.username = username
client.password = password
}
}
// ClientOptWriter returns a function that sets the writer setting on client options set // ClientOptWriter returns a function that sets the writer setting on client options set
func ClientOptWriter(out io.Writer) ClientOption { func ClientOptWriter(out io.Writer) ClientOption {
return func(client *Client) { return func(client *Client) {

@ -89,6 +89,7 @@ func setup(suite *TestSuite, tlsEnabled, insecure bool) *registry.Registry {
ClientOptWriter(suite.Out), ClientOptWriter(suite.Out),
ClientOptCredentialsFile(credentialsFile), ClientOptCredentialsFile(credentialsFile),
ClientOptResolver(nil), ClientOptResolver(nil),
ClientOptBasicAuth(testUsername, testPassword),
} }
if tlsEnabled { if tlsEnabled {
@ -128,11 +129,12 @@ func setup(suite *TestSuite, tlsEnabled, insecure bool) *registry.Registry {
// This is required because Docker enforces HTTP if the registry // This is required because Docker enforces HTTP if the registry
// host is localhost/127.0.0.1. // host is localhost/127.0.0.1.
suite.DockerRegistryHost = fmt.Sprintf("helm-test-registry:%d", port) suite.DockerRegistryHost = fmt.Sprintf("helm-test-registry:%d", port)
suite.srv, _ = mockdns.NewServer(map[string]mockdns.Zone{ suite.srv, err = mockdns.NewServer(map[string]mockdns.Zone{
"helm-test-registry.": { "helm-test-registry.": {
A: []string{"127.0.0.1"}, A: []string{"127.0.0.1"},
}, },
}, false) }, false)
suite.Nil(err, "no error creating mock DNS server")
suite.srv.PatchNet(net.DefaultResolver) suite.srv.PatchNet(net.DefaultResolver)
config.HTTP.Addr = fmt.Sprintf(":%d", port) config.HTTP.Addr = fmt.Sprintf(":%d", port)
@ -349,7 +351,7 @@ func testPull(suite *TestSuite) {
// full pull with chart and prov // full pull with chart and prov
result, err := suite.RegistryClient.Pull(ref, PullOptWithProv(true)) result, err := suite.RegistryClient.Pull(ref, PullOptWithProv(true))
suite.Nil(err, "no error pulling a chart with prov") suite.Require().Nil(err, "no error pulling a chart with prov")
// Validate the output // Validate the output
// Note: these digests/sizes etc may change if the test chart/prov files are modified, // Note: these digests/sizes etc may change if the test chart/prov files are modified,

Loading…
Cancel
Save