From e6bb8282db510264bb36eb42aee9b248782574d3 Mon Sep 17 00:00:00 2001 From: KUOKA Yusuke Date: Tue, 25 Jun 2019 12:45:56 +0900 Subject: [PATCH] fix: remote helmfile from git::ssh source (#719) The remote helmfile feature introduced by #648 was unable to be sourced from private git repositories due to URL parsing issue in helmfile. This fixes that. Ref https://github.com/roboll/helmfile/issues/469#issuecomment-505236600 --- pkg/remote/remote.go | 15 +++++--- pkg/remote/remote_test.go | 73 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 82 insertions(+), 6 deletions(-) diff --git a/pkg/remote/remote.go b/pkg/remote/remote.go index a0e13e69..ca60f88b 100644 --- a/pkg/remote/remote.go +++ b/pkg/remote/remote.go @@ -100,7 +100,7 @@ func (e InvalidURLError) Error() string { } type Source struct { - Getter, Scheme, Host, Dir, File, RawQuery string + Getter, Scheme, User, Host, Dir, File, RawQuery string } func IsRemote(goGetterSrc string) bool { @@ -135,6 +135,7 @@ func Parse(goGetterSrc string) (*Source, error) { return &Source{ Getter: getter, + User: u.User.String(), Scheme: u.Scheme, Host: u.Host, Dir: pathComponents[0], @@ -154,6 +155,7 @@ func (r *Remote) Fetch(goGetterSrc string) (string, error) { r.Logger.Debugf("getter: %s", u.Getter) r.Logger.Debugf("scheme: %s", u.Scheme) + r.Logger.Debugf("user: %s", u.User) r.Logger.Debugf("host: %s", u.Host) r.Logger.Debugf("dir: %s", u.Dir) r.Logger.Debugf("file: %s", u.File) @@ -195,11 +197,14 @@ func (r *Remote) Fetch(goGetterSrc string) (string, error) { if !cached { var getterSrc string - - if len(query) == 0 { - getterSrc = srcDir + if u.User != "" { + getterSrc = fmt.Sprintf("%s://%s@%s%s", u.Scheme, u.User, u.Host, u.Dir) } else { - getterSrc = strings.Join([]string{srcDir, query}, "?") + getterSrc = fmt.Sprintf("%s://%s%s", u.Scheme, u.Host, u.Dir) + } + + if len(query) > 0 { + getterSrc = strings.Join([]string{getterSrc, query}, "?") } if u.Getter != "" { diff --git a/pkg/remote/remote_test.go b/pkg/remote/remote_test.go index 86e5de3d..357f5707 100644 --- a/pkg/remote/remote_test.go +++ b/pkg/remote/remote_test.go @@ -8,7 +8,7 @@ import ( "testing" ) -func TestRemote(t *testing.T) { +func TestRemote_HttpsGitHub(t *testing.T) { cleanfs := map[string]string{ "path/to/home": "", } @@ -85,6 +85,77 @@ func TestRemote(t *testing.T) { } } +func TestRemote_SShGitHub(t *testing.T) { + cleanfs := map[string]string{ + "path/to/home": "", + } + cachefs := map[string]string{ + "path/to/home/.helmfile/cache/ssh_github_com_cloudposse_helmfiles_git.ref=0.40.0/releases/kiam.yaml": "foo: bar", + } + + type testcase struct { + files map[string]string + expectCacheHit bool + } + + testcases := []testcase{ + {files: cleanfs, expectCacheHit: false}, + {files: cachefs, expectCacheHit: true}, + } + + for i := range testcases { + testcase := testcases[i] + + t.Run(fmt.Sprintf("case %d", i), func(t *testing.T) { + testfs := testhelper.NewTestFs(testcase.files) + + hit := true + + get := func(wd, src, dst string) error { + if wd != "path/to/home" { + return fmt.Errorf("unexpected wd: %s", wd) + } + if src != "git::ssh://git@github.com/cloudposse/helmfiles.git?ref=0.40.0" { + return fmt.Errorf("unexpected src: %s", src) + } + + hit = false + + return nil + } + + getter := &testGetter{ + get: get, + } + remote := &Remote{ + Logger: helmexec.NewLogger(os.Stderr, "debug"), + Home: "path/to/home", + Getter: getter, + ReadFile: testfs.ReadFile, + FileExists: testfs.FileExistsAt, + DirExists: testfs.DirectoryExistsAt, + } + + url := "git::ssh://git@github.com/cloudposse/helmfiles.git@releases/kiam.yaml?ref=0.40.0" + file, err := remote.Locate(url) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + if file != "path/to/home/.helmfile/cache/ssh_github_com_cloudposse_helmfiles_git.ref=0.40.0/releases/kiam.yaml" { + t.Errorf("unexpected file located: %s", file) + } + + if testcase.expectCacheHit && !hit { + t.Errorf("unexpected result: unexpected cache miss") + } + if !testcase.expectCacheHit && hit { + t.Errorf("unexpected result: unexpected cache hit") + } + }) + } +} + type testGetter struct { get func(wd, src, dst string) error }