Authentication support for remote charts repositories.

pull/3206/head^2
eyalbe4 8 years ago
parent 87f66af061
commit b3b5366d55

@ -52,6 +52,8 @@ type fetchCmd struct {
destdir string destdir string
version string version string
repoURL string repoURL string
username string
password string
verify bool verify bool
verifyLater bool verifyLater bool
@ -138,14 +140,14 @@ func (f *fetchCmd) run() error {
} }
if f.repoURL != "" { if f.repoURL != "" {
chartURL, err := repo.FindChartInRepoURL(f.repoURL, f.chartRef, f.version, f.certFile, f.keyFile, f.caFile, getter.All(settings)) chartURL, err := repo.FindChartInRepoURL(f.repoURL, f.username, f.password, f.chartRef, f.version, f.certFile, f.keyFile, f.caFile, getter.All(settings))
if err != nil { if err != nil {
return err return err
} }
f.chartRef = chartURL f.chartRef = chartURL
} }
saved, v, err := c.DownloadTo(f.chartRef, f.version, dest) saved, v, err := c.DownloadTo(f.chartRef, f.username, f.password, f.version, dest)
if err != nil { if err != nil {
return err return err
} }

@ -59,6 +59,8 @@ type inspectCmd struct {
out io.Writer out io.Writer
version string version string
repoURL string repoURL string
username string
password string
certFile string certFile string
keyFile string keyFile string
@ -88,7 +90,7 @@ func newInspectCmd(out io.Writer) *cobra.Command {
if err := checkArgsLength(len(args), "chart name"); err != nil { if err := checkArgsLength(len(args), "chart name"); err != nil {
return err return err
} }
cp, err := locateChartPath(insp.repoURL, args[0], insp.version, insp.verify, insp.keyring, cp, err := locateChartPath(insp.repoURL, insp.username, insp.password, args[0], insp.version, insp.verify, insp.keyring,
insp.certFile, insp.keyFile, insp.caFile) insp.certFile, insp.keyFile, insp.caFile)
if err != nil { if err != nil {
return err return err
@ -107,7 +109,7 @@ func newInspectCmd(out io.Writer) *cobra.Command {
if err := checkArgsLength(len(args), "chart name"); err != nil { if err := checkArgsLength(len(args), "chart name"); err != nil {
return err return err
} }
cp, err := locateChartPath(insp.repoURL, args[0], insp.version, insp.verify, insp.keyring, cp, err := locateChartPath(insp.repoURL, insp.username, insp.password, args[0], insp.version, insp.verify, insp.keyring,
insp.certFile, insp.keyFile, insp.caFile) insp.certFile, insp.keyFile, insp.caFile)
if err != nil { if err != nil {
return err return err
@ -126,7 +128,7 @@ func newInspectCmd(out io.Writer) *cobra.Command {
if err := checkArgsLength(len(args), "chart name"); err != nil { if err := checkArgsLength(len(args), "chart name"); err != nil {
return err return err
} }
cp, err := locateChartPath(insp.repoURL, args[0], insp.version, insp.verify, insp.keyring, cp, err := locateChartPath(insp.repoURL, insp.username, insp.password, args[0], insp.version, insp.verify, insp.keyring,
insp.certFile, insp.keyFile, insp.caFile) insp.certFile, insp.keyFile, insp.caFile)
if err != nil { if err != nil {
return err return err
@ -181,6 +183,18 @@ func newInspectCmd(out io.Writer) *cobra.Command {
subCmd.Flags().StringVar(&insp.repoURL, repoURL, "", repoURLdesc) subCmd.Flags().StringVar(&insp.repoURL, repoURL, "", repoURLdesc)
} }
username := "username"
usernamedesc := "chart repository username where to locate the requested chart"
inspectCommand.Flags().StringVar(&insp.username, username, "", usernamedesc)
valuesSubCmd.Flags().StringVar(&insp.username, username, "", usernamedesc)
chartSubCmd.Flags().StringVar(&insp.username, username, "", usernamedesc)
password := "password"
passworddesc := "chart repository password where to locate the requested chart"
inspectCommand.Flags().StringVar(&insp.password, password, "", passworddesc)
valuesSubCmd.Flags().StringVar(&insp.password, password, "", passworddesc)
chartSubCmd.Flags().StringVar(&insp.password, password, "", passworddesc)
certFile := "cert-file" certFile := "cert-file"
certFiledesc := "verify certificates of HTTPS-enabled servers using this CA bundle" certFiledesc := "verify certificates of HTTPS-enabled servers using this CA bundle"
for _, subCmd := range cmds { for _, subCmd := range cmds {

@ -118,6 +118,8 @@ type installCmd struct {
timeout int64 timeout int64
wait bool wait bool
repoURL string repoURL string
username string
password string
devel bool devel bool
depUp bool depUp bool
@ -165,7 +167,7 @@ func newInstallCmd(c helm.Interface, out io.Writer) *cobra.Command {
inst.version = ">0.0.0-0" inst.version = ">0.0.0-0"
} }
cp, err := locateChartPath(inst.repoURL, args[0], inst.version, inst.verify, inst.keyring, cp, err := locateChartPath(inst.repoURL, inst.username, inst.password, args[0], inst.version, inst.verify, inst.keyring,
inst.certFile, inst.keyFile, inst.caFile) inst.certFile, inst.keyFile, inst.caFile)
if err != nil { if err != nil {
return err return err
@ -191,6 +193,8 @@ func newInstallCmd(c helm.Interface, out io.Writer) *cobra.Command {
f.Int64Var(&inst.timeout, "timeout", 300, "time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks)") f.Int64Var(&inst.timeout, "timeout", 300, "time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks)")
f.BoolVar(&inst.wait, "wait", false, "if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as --timeout") f.BoolVar(&inst.wait, "wait", false, "if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as --timeout")
f.StringVar(&inst.repoURL, "repo", "", "chart repository url where to locate the requested chart") f.StringVar(&inst.repoURL, "repo", "", "chart repository url where to locate the requested chart")
f.StringVar(&inst.username, "username", "", "chart repository username where to locate the requested chart")
f.StringVar(&inst.password, "password", "", "chart repository password where to locate the requested chart")
f.StringVar(&inst.certFile, "cert-file", "", "identify HTTPS client using this SSL certificate file") f.StringVar(&inst.certFile, "cert-file", "", "identify HTTPS client using this SSL certificate file")
f.StringVar(&inst.keyFile, "key-file", "", "identify HTTPS client using this SSL key file") f.StringVar(&inst.keyFile, "key-file", "", "identify HTTPS client using this SSL key file")
f.StringVar(&inst.caFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle") f.StringVar(&inst.caFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle")
@ -381,8 +385,8 @@ func (i *installCmd) printRelease(rel *release.Release) {
// - URL // - URL
// //
// If 'verify' is true, this will attempt to also verify the chart. // If 'verify' is true, this will attempt to also verify the chart.
func locateChartPath(repoURL, name, version string, verify bool, keyring, func locateChartPath(repoURL, username, password, name, version string, verify bool, keyring,
certFile, keyFile, caFile string) (string, error) { certFile, keyFile, caFile string) (string, error) {
name = strings.TrimSpace(name) name = strings.TrimSpace(name)
version = strings.TrimSpace(version) version = strings.TrimSpace(version)
if fi, err := os.Stat(name); err == nil { if fi, err := os.Stat(name); err == nil {
@ -419,7 +423,7 @@ func locateChartPath(repoURL, name, version string, verify bool, keyring,
dl.Verify = downloader.VerifyAlways dl.Verify = downloader.VerifyAlways
} }
if repoURL != "" { if repoURL != "" {
chartURL, err := repo.FindChartInRepoURL(repoURL, name, version, chartURL, err := repo.FindChartInRepoURL(repoURL, username, password, name, version,
certFile, keyFile, caFile, getter.All(settings)) certFile, keyFile, caFile, getter.All(settings))
if err != nil { if err != nil {
return "", err return "", err
@ -431,7 +435,7 @@ func locateChartPath(repoURL, name, version string, verify bool, keyring,
os.MkdirAll(settings.Home.Archive(), 0744) os.MkdirAll(settings.Home.Archive(), 0744)
} }
filename, _, err := dl.DownloadTo(name, version, settings.Home.Archive()) filename, _, err := dl.DownloadTo(name, username, password, version, settings.Home.Archive())
if err == nil { if err == nil {
lname, err := filepath.Abs(filename) lname, err := filepath.Abs(filename)
if err != nil { if err != nil {

@ -30,6 +30,8 @@ import (
type repoAddCmd struct { type repoAddCmd struct {
name string name string
url string url string
username string
password string
home helmpath.Home home helmpath.Home
noupdate bool noupdate bool
@ -44,15 +46,31 @@ func newRepoAddCmd(out io.Writer) *cobra.Command {
add := &repoAddCmd{out: out} add := &repoAddCmd{out: out}
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "add [flags] [NAME] [URL]", Use: "add [flags] [NAME] [URL] [USERNAME] [PASSWORD]",
Short: "add a chart repository", Short: "add a chart repository",
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
if err := checkArgsLength(len(args), "name for the chart repository", "the url of the chart repository"); err != nil { argsDesc := []string {
"name for the chart repository",
"the url of the chart repository",
"the username for the chart repository",
"the password of the chart repository",
}
if len(args) <= 2 {
if err := checkArgsLength(len(args), argsDesc[0], argsDesc[1]); err != nil {
return err
}
} else
if err := checkArgsLength(len(args), argsDesc[0], argsDesc[1], argsDesc[2], argsDesc[3]); err != nil {
return err return err
} }
add.name = args[0] add.name = args[0]
add.url = args[1] add.url = args[1]
if len(args) == 4 {
add.username = args[2]
add.password = args[3]
}
add.home = settings.Home add.home = settings.Home
return add.run() return add.run()
@ -69,14 +87,14 @@ func newRepoAddCmd(out io.Writer) *cobra.Command {
} }
func (a *repoAddCmd) run() error { func (a *repoAddCmd) run() error {
if err := addRepository(a.name, a.url, a.home, a.certFile, a.keyFile, a.caFile, a.noupdate); err != nil { if err := addRepository(a.name, a.url, a.username, a.password , a.home, a.certFile, a.keyFile, a.caFile, a.noupdate); err != nil {
return err return err
} }
fmt.Fprintf(a.out, "%q has been added to your repositories\n", a.name) fmt.Fprintf(a.out, "%q has been added to your repositories\n", a.name)
return nil return nil
} }
func addRepository(name, url string, home helmpath.Home, certFile, keyFile, caFile string, noUpdate bool) error { func addRepository(name, url, username, password string, home helmpath.Home, certFile, keyFile, caFile string, noUpdate bool) error {
f, err := repo.LoadRepositoriesFile(home.RepositoryFile()) f, err := repo.LoadRepositoriesFile(home.RepositoryFile())
if err != nil { if err != nil {
return err return err
@ -91,6 +109,8 @@ func addRepository(name, url string, home helmpath.Home, certFile, keyFile, caFi
Name: name, Name: name,
Cache: cif, Cache: cif,
URL: url, URL: url,
Username: username,
Password: password,
CertFile: certFile, CertFile: certFile,
KeyFile: keyFile, KeyFile: keyFile,
CAFile: caFile, CAFile: caFile,

@ -73,6 +73,8 @@ type upgradeCmd struct {
reuseValues bool reuseValues bool
wait bool wait bool
repoURL string repoURL string
username string
password string
devel bool devel bool
certFile string certFile string
@ -128,6 +130,8 @@ func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command {
f.BoolVar(&upgrade.reuseValues, "reuse-values", false, "when upgrading, reuse the last release's values, and merge in any new values. If '--reset-values' is specified, this is ignored.") f.BoolVar(&upgrade.reuseValues, "reuse-values", false, "when upgrading, reuse the last release's values, and merge in any new values. If '--reset-values' is specified, this is ignored.")
f.BoolVar(&upgrade.wait, "wait", false, "if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as --timeout") f.BoolVar(&upgrade.wait, "wait", false, "if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as --timeout")
f.StringVar(&upgrade.repoURL, "repo", "", "chart repository url where to locate the requested chart") f.StringVar(&upgrade.repoURL, "repo", "", "chart repository url where to locate the requested chart")
f.StringVar(&upgrade.username, "username", "", "chart repository username where to locate the requested chart")
f.StringVar(&upgrade.password, "password", "", "chart repository password where to locate the requested chart")
f.StringVar(&upgrade.certFile, "cert-file", "", "identify HTTPS client using this SSL certificate file") f.StringVar(&upgrade.certFile, "cert-file", "", "identify HTTPS client using this SSL certificate file")
f.StringVar(&upgrade.keyFile, "key-file", "", "identify HTTPS client using this SSL key file") f.StringVar(&upgrade.keyFile, "key-file", "", "identify HTTPS client using this SSL key file")
f.StringVar(&upgrade.caFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle") f.StringVar(&upgrade.caFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle")
@ -139,7 +143,7 @@ func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command {
} }
func (u *upgradeCmd) run() error { func (u *upgradeCmd) run() error {
chartPath, err := locateChartPath(u.repoURL, u.chart, u.version, u.verify, u.keyring, u.certFile, u.keyFile, u.caFile) chartPath, err := locateChartPath(u.repoURL, u.username, u.password, u.chart, u.version, u.verify, u.keyring, u.certFile, u.keyFile, u.caFile)
if err != nil { if err != nil {
return err return err
} }

@ -80,13 +80,13 @@ type ChartDownloader struct {
// //
// Returns a string path to the location where the file was downloaded and a verification // Returns a string path to the location where the file was downloaded and a verification
// (if provenance was verified), or an error if something bad happened. // (if provenance was verified), or an error if something bad happened.
func (c *ChartDownloader) DownloadTo(ref, version, dest string) (string, *provenance.Verification, error) { func (c *ChartDownloader) DownloadTo(ref, username, password, version, dest string) (string, *provenance.Verification, error) {
u, g, err := c.ResolveChartVersion(ref, version) u, g, err := c.ResolveChartVersion(ref, version)
if err != nil { if err != nil {
return "", nil, err return "", nil, err
} }
data, err := g.Get(u.String()) data, err := g.GetWithCredentials(u.String(), username, password)
if err != nil { if err != nil {
return "", nil, err return "", nil, err
} }

@ -195,7 +195,7 @@ func TestDownloadTo(t *testing.T) {
Getters: getter.All(environment.EnvSettings{}), Getters: getter.All(environment.EnvSettings{}),
} }
cname := "/signtest-0.1.0.tgz" cname := "/signtest-0.1.0.tgz"
where, v, err := c.DownloadTo(srv.URL()+cname, "", dest) where, v, err := c.DownloadTo(srv.URL()+cname, "", "", "", dest)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
return return
@ -258,7 +258,7 @@ func TestDownloadTo_VerifyLater(t *testing.T) {
Getters: getter.All(environment.EnvSettings{}), Getters: getter.All(environment.EnvSettings{}),
} }
cname := "/signtest-0.1.0.tgz" cname := "/signtest-0.1.0.tgz"
where, _, err := c.DownloadTo(srv.URL()+cname, "", dest) where, _, err := c.DownloadTo(srv.URL()+cname,"", "", "", dest)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
return return

@ -245,13 +245,13 @@ func (m *Manager) downloadAll(deps []*chartutil.Dependency) error {
// Any failure to resolve/download a chart should fail: // Any failure to resolve/download a chart should fail:
// https://github.com/kubernetes/helm/issues/1439 // https://github.com/kubernetes/helm/issues/1439
churl, err := findChartURL(dep.Name, dep.Version, dep.Repository, repos) churl, username, password, err := findChartURL(dep.Name, dep.Version, dep.Repository, repos)
if err != nil { if err != nil {
saveError = fmt.Errorf("could not find %s: %s", churl, err) saveError = fmt.Errorf("could not find %s: %s", churl, err)
break break
} }
if _, _, err := dl.DownloadTo(churl, "", destPath); err != nil { if _, _, err := dl.DownloadTo(churl, username, password, "", destPath); err != nil {
saveError = fmt.Errorf("could not download %s: %s", churl, err) saveError = fmt.Errorf("could not download %s: %s", churl, err)
break break
} }
@ -476,22 +476,30 @@ func (m *Manager) parallelRepoUpdate(repos []*repo.Entry) error {
// repoURL is the repository to search // repoURL is the repository to search
// //
// If it finds a URL that is "relative", it will prepend the repoURL. // If it finds a URL that is "relative", it will prepend the repoURL.
func findChartURL(name, version, repoURL string, repos map[string]*repo.ChartRepository) (string, error) { func findChartURL(name, version, repoURL string, repos map[string]*repo.ChartRepository) (url, username, password string, err error) {
for _, cr := range repos { for _, cr := range repos {
if urlutil.Equal(repoURL, cr.Config.URL) { if urlutil.Equal(repoURL, cr.Config.URL) {
entry, err := findEntryByName(name, cr) var entry repo.ChartVersions
entry, err = findEntryByName(name, cr)
if err != nil { if err != nil {
return "", err return
} }
ve, err := findVersionedEntry(version, entry) var ve *repo.ChartVersion
ve, err = findVersionedEntry(version, entry)
if err != nil { if err != nil {
return "", err return
} }
url, err = normalizeURL(repoURL, ve.URLs[0])
return normalizeURL(repoURL, ve.URLs[0]) if err != nil {
return
}
username = cr.Config.Username
password = cr.Config.Password
return
} }
} }
return "", fmt.Errorf("chart %s not found in %s", name, repoURL) err = fmt.Errorf("chart %s not found in %s", name, repoURL)
return
} }
// findEntryByName finds an entry in the chart repository whose name matches the given name. // findEntryByName finds an entry in the chart repository whose name matches the given name.

@ -77,14 +77,19 @@ func TestFindChartURL(t *testing.T) {
version := "0.1.0" version := "0.1.0"
repoURL := "http://example.com/charts" repoURL := "http://example.com/charts"
churl, err := findChartURL(name, version, repoURL, repos) churl, username, password, err := findChartURL(name, version, repoURL, repos)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if churl != "https://kubernetes-charts.storage.googleapis.com/alpine-0.1.0.tgz" { if churl != "https://kubernetes-charts.storage.googleapis.com/alpine-0.1.0.tgz" {
t.Errorf("Unexpected URL %q", churl) t.Errorf("Unexpected URL %q", churl)
} }
if username != "" {
t.Errorf("Unexpected username %q", username)
}
if password != "" {
t.Errorf("Unexpected password %q", password)
}
} }
func TestGetRepoNames(t *testing.T) { func TestGetRepoNames(t *testing.T) {

@ -27,6 +27,8 @@ import (
type Getter interface { type Getter interface {
//Get file content by url string //Get file content by url string
Get(url string) (*bytes.Buffer, error) Get(url string) (*bytes.Buffer, error)
//Get file content by url, username and password strings
GetWithCredentials(href, username, password string) (*bytes.Buffer, error)
} }
// Constructor is the function for every getter which creates a specific instance // Constructor is the function for every getter which creates a specific instance

@ -34,6 +34,15 @@ type httpGetter struct {
//Get performs a Get from repo.Getter and returns the body. //Get performs a Get from repo.Getter and returns the body.
func (g *httpGetter) Get(href string) (*bytes.Buffer, error) { func (g *httpGetter) Get(href string) (*bytes.Buffer, error) {
return g.get(href, "", "")
}
//Get performs a Get from repo.Getter using credentials and returns the body.
func (g *httpGetter) GetWithCredentials(href, username, password string) (*bytes.Buffer, error) {
return g.get(href, username, password)
}
func (g *httpGetter) get(href, username, password string) (*bytes.Buffer, error) {
buf := bytes.NewBuffer(nil) buf := bytes.NewBuffer(nil)
// Set a helm specific user agent so that a repo server and metrics can // Set a helm specific user agent so that a repo server and metrics can
@ -44,6 +53,10 @@ func (g *httpGetter) Get(href string) (*bytes.Buffer, error) {
} }
req.Header.Set("User-Agent", "Helm/"+strings.TrimPrefix(version.GetVersion(), "v")) req.Header.Set("User-Agent", "Helm/"+strings.TrimPrefix(version.GetVersion(), "v"))
if username != "" && password != "" {
req.SetBasicAuth(username, password)
}
resp, err := g.client.Do(req) resp, err := g.client.Do(req)
if err != nil { if err != nil {
return buf, err return buf, err

@ -79,6 +79,10 @@ func (p *pluginGetter) Get(href string) (*bytes.Buffer, error) {
return buf, nil return buf, nil
} }
func (p *pluginGetter) GetWithCredentials(href, username, password string) (*bytes.Buffer, error) {
return p.Get(href)
}
// newPluginGetter constructs a valid plugin getter // newPluginGetter constructs a valid plugin getter
func newPluginGetter(command string, settings environment.EnvSettings, name, base string) Constructor { func newPluginGetter(command string, settings environment.EnvSettings, name, base string) Constructor {
return func(URL, CertFile, KeyFile, CAFile string) (Getter, error) { return func(URL, CertFile, KeyFile, CAFile string) (Getter, error) {

@ -35,6 +35,8 @@ type TestHTTPGetter struct {
func (t *TestHTTPGetter) Get(href string) (*bytes.Buffer, error) { return t.MockResponse, t.MockError } func (t *TestHTTPGetter) Get(href string) (*bytes.Buffer, error) { return t.MockResponse, t.MockError }
func (t *TestHTTPGetter) GetWithCredentials(href, username, password string) (*bytes.Buffer, error) { return t.MockResponse, t.MockError }
// Fake plugin tarball data // Fake plugin tarball data
var fakePluginB64 = "H4sIAKRj51kAA+3UX0vCUBgGcC9jn+Iwuk3Peza3GeyiUlJQkcogCOzgli7dJm4TvYk+a5+k479UqquUCJ/fLs549sLO2TnvWnJa9aXnjwujYdYLovxMhsPcfnHOLdNkOXthM/IVQQYjg2yyLLJ4kXGhLp5j0z3P41tZksqxmspL3B/O+j/XtZu1y8rdYzkOZRCxduKPk53ny6Wwz/GfIIf1As8lxzGJSmoHNLJZphKHG4YpTCE0wVk3DULfpSJ3DMMqkj3P5JfMYLdX1Vr9Ie/5E5cstcdC8K04iGLX5HaJuKpWL17F0TCIBi5pf/0pjtLhun5j3f9v6r7wfnI/H0eNp9d1/5P6Gez0vzo7wsoxfrAZbTny/o9k6J8z/VkO/LPlWdC1iVpbEEcq5nmeJ13LEtmbV0k2r2PrOs9PuuNglC5rL1Y5S/syXRQmutaNw1BGnnp8Wq3UG51WvX1da3bKtZtCN/R09DwAAAAAAAAAAAAAAAAAAADAb30AoMczDwAoAAA=" var fakePluginB64 = "H4sIAKRj51kAA+3UX0vCUBgGcC9jn+Iwuk3Peza3GeyiUlJQkcogCOzgli7dJm4TvYk+a5+k479UqquUCJ/fLs549sLO2TnvWnJa9aXnjwujYdYLovxMhsPcfnHOLdNkOXthM/IVQQYjg2yyLLJ4kXGhLp5j0z3P41tZksqxmspL3B/O+j/XtZu1y8rdYzkOZRCxduKPk53ny6Wwz/GfIIf1As8lxzGJSmoHNLJZphKHG4YpTCE0wVk3DULfpSJ3DMMqkj3P5JfMYLdX1Vr9Ie/5E5cstcdC8K04iGLX5HaJuKpWL17F0TCIBi5pf/0pjtLhun5j3f9v6r7wfnI/H0eNp9d1/5P6Gez0vzo7wsoxfrAZbTny/o9k6J8z/VkO/LPlWdC1iVpbEEcq5nmeJ13LEtmbV0k2r2PrOs9PuuNglC5rL1Y5S/syXRQmutaNw1BGnnp8Wq3UG51WvX1da3bKtZtCN/R09DwAAAAAAAAAAAAAAAAAAADAb30AoMczDwAoAAA="

@ -29,6 +29,7 @@ import (
"k8s.io/helm/pkg/chartutil" "k8s.io/helm/pkg/chartutil"
"k8s.io/helm/pkg/getter" "k8s.io/helm/pkg/getter"
"k8s.io/helm/pkg/provenance" "k8s.io/helm/pkg/provenance"
"bytes"
) )
// Entry represents a collection of parameters for chart repository // Entry represents a collection of parameters for chart repository
@ -36,6 +37,8 @@ type Entry struct {
Name string `json:"name"` Name string `json:"name"`
Cache string `json:"cache"` Cache string `json:"cache"`
URL string `json:"url"` URL string `json:"url"`
Username string `json:"username"`
Password string `json:"password"`
CertFile string `json:"certFile"` CertFile string `json:"certFile"`
KeyFile string `json:"keyFile"` KeyFile string `json:"keyFile"`
CAFile string `json:"caFile"` CAFile string `json:"caFile"`
@ -117,7 +120,13 @@ func (r *ChartRepository) DownloadIndexFile(cachePath string) error {
parsedURL.Path = strings.TrimSuffix(parsedURL.Path, "/") + "/index.yaml" parsedURL.Path = strings.TrimSuffix(parsedURL.Path, "/") + "/index.yaml"
indexURL = parsedURL.String() indexURL = parsedURL.String()
resp, err := r.Client.Get(indexURL) var resp *bytes.Buffer
if r.Config.Username == "" || r.Config.Password == "" {
resp, err = r.Client.Get(indexURL)
} else {
resp, err = r.Client.GetWithCredentials(indexURL, r.Config.Username, r.Config.Password)
}
if err != nil { if err != nil {
return err return err
} }
@ -185,7 +194,7 @@ func (r *ChartRepository) generateIndex() error {
// FindChartInRepoURL finds chart in chart repository pointed by repoURL // FindChartInRepoURL finds chart in chart repository pointed by repoURL
// without adding repo to repositories // without adding repo to repositories
func FindChartInRepoURL(repoURL, chartName, chartVersion, certFile, keyFile, caFile string, getters getter.Providers) (string, error) { func FindChartInRepoURL(repoURL, username, password, chartName, chartVersion, certFile, keyFile, caFile string, getters getter.Providers) (string, error) {
// Download and write the index file to a temporary location // Download and write the index file to a temporary location
tempIndexFile, err := ioutil.TempFile("", "tmp-repo-file") tempIndexFile, err := ioutil.TempFile("", "tmp-repo-file")
@ -196,6 +205,8 @@ func FindChartInRepoURL(repoURL, chartName, chartVersion, certFile, keyFile, caF
c := Entry{ c := Entry{
URL: repoURL, URL: repoURL,
Username: username,
Password: password,
CertFile: certFile, CertFile: certFile,
KeyFile: keyFile, KeyFile: keyFile,
CAFile: caFile, CAFile: caFile,

Loading…
Cancel
Save