From 800f8c4afb08eba3137c61234943ad09cd922d9c Mon Sep 17 00:00:00 2001 From: Andreas Karis Date: Tue, 1 Jun 2021 14:58:31 +0200 Subject: [PATCH] fix(helm): helm pull --repo to use repo creds from helm repos file Up to this point, helm pull --repo required --username and --password even if the repository had already been added via helm repo add. From now on, check repositories in the repositories file and if the URL matches, pull the chart with the username and password from the entry. Fixes #9599 Signed-off-by: Andreas Karis --- pkg/action/pull.go | 14 +++++++++++- pkg/repo/repo.go | 22 +++++++++++++++++++ pkg/repo/repo_test.go | 50 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 1 deletion(-) diff --git a/pkg/action/pull.go b/pkg/action/pull.go index 787553125..e0488c892 100644 --- a/pkg/action/pull.go +++ b/pkg/action/pull.go @@ -122,7 +122,19 @@ func (p *Pull) Run(chartRef string) (string, error) { } if p.RepoURL != "" { - chartURL, err := repo.FindChartInAuthAndTLSAndPassRepoURL(p.RepoURL, p.Username, p.Password, chartRef, p.Version, p.CertFile, p.KeyFile, p.CaFile, p.InsecureSkipTLSverify, p.PassCredentialsAll, getter.All(p.Settings)) + username := p.Username + password := p.Password + if username == "" && password == "" { + repoEntry, err := repo.FindRepoEntry(p.RepoURL, p.Settings.RepositoryConfig) + if err != nil { + return out.String(), err + } + if repoEntry != nil { + username = repoEntry.Username + password = repoEntry.Password + } + } + chartURL, err := repo.FindChartInAuthAndTLSAndPassRepoURL(p.RepoURL, username, password, chartRef, p.Version, p.CertFile, p.KeyFile, p.CaFile, p.InsecureSkipTLSverify, p.PassCredentialsAll, getter.All(p.Settings)) if err != nil { return out.String(), err } diff --git a/pkg/repo/repo.go b/pkg/repo/repo.go index 834d554bd..a3c8f0525 100644 --- a/pkg/repo/repo.go +++ b/pkg/repo/repo.go @@ -94,6 +94,28 @@ func (r *File) Get(name string) *Entry { return nil } +// Get returns an entry with the given URL if it exists, otherwise returns nil +func (r *File) GetURL(url string) *Entry { + for _, entry := range r.Repositories { + if entry.URL == url { + return entry + } + } + return nil +} + +func FindRepoEntry(url string, repositoryConfig string) (*Entry, error) { + f, err := LoadFile(repositoryConfig) + if err != nil { + return nil, err + } + entry := f.GetURL(url) + if entry == nil { + return nil, nil + } + return entry, nil +} + // Remove removes the entry from the list of repositories. func (r *File) Remove(name string) bool { cp := []*Entry{} diff --git a/pkg/repo/repo_test.go b/pkg/repo/repo_test.go index c2087ebbe..5c39952df 100644 --- a/pkg/repo/repo_test.go +++ b/pkg/repo/repo_test.go @@ -128,6 +128,56 @@ func TestRepoFile_Get(t *testing.T) { } } +func TestRepoFile_GetURL(t *testing.T) { + repo := NewFile() + repo.Add( + &Entry{ + Name: "first", + URL: "https://example.com/first", + }, + &Entry{ + Name: "second", + URL: "https://example.com/second", + }, + &Entry{ + Name: "third", + URL: "https://example.com/third", + }, + &Entry{ + Name: "fourth", + URL: "https://example.com/fourth", + }, + ) + + url := "https://example.com/second" + + entry := repo.GetURL(url) + if entry == nil { + t.Fatalf("Expected repo entry %q to be found", url) + } + + if entry.Name != "second" { + t.Errorf("Expected repo Name to be %q but got %q", "second", entry.Name) + } + + entry = repo.GetURL("http://nonexistent.example.com/nonexistent") + if entry != nil { + t.Errorf("Got unexpected entry %+v", entry) + } +} + +func TestFindRepoEntry(t *testing.T) { + url := "https://example.com/incubator" + repoEntry, err := FindRepoEntry(url, testRepositoriesFile) + if err != nil { + t.Errorf("%q could not be loaded: %s", testRepositoriesFile, err) + } + + if repoEntry == nil { + t.Fatalf("Could not find repository with URL: %q", url) + } +} + func TestRemoveRepository(t *testing.T) { sampleRepository := NewFile() sampleRepository.Add(