From 04dc670522257423bfcb38b7e3cd1429dd86cb4c Mon Sep 17 00:00:00 2001 From: jackgr Date: Sun, 27 Mar 2016 16:26:03 -0700 Subject: [PATCH 1/6] Chart repo route tests --- cmd/manager/chartrepos.go | 36 ++++++++ cmd/manager/chartrepos_test.go | 147 ++++++++++++++++++++++++++++++++- pkg/repo/gcs_repo.go | 2 +- 3 files changed, 180 insertions(+), 5 deletions(-) diff --git a/cmd/manager/chartrepos.go b/cmd/manager/chartrepos.go index c94107dbc..55ea07f34 100644 --- a/cmd/manager/chartrepos.go +++ b/cmd/manager/chartrepos.go @@ -159,3 +159,39 @@ func getRepoChartHandlerFunc(w http.ResponseWriter, r *http.Request, c *router.C util.LogHandlerExitWithJSON(handler, w, repoChart, http.StatusOK) return nil } + +func addChartRepoHandlerFunc(w http.ResponseWriter, r *http.Request, c *router.Context) error { + handler := "manager: add chart repository" + util.LogHandlerEntry(handler, r) + defer r.Body.Close() + cr := &repo.Repo{} + if err := httputil.Decode(w, r, cr); err != nil { + httputil.BadRequest(w, r, err) + return nil + } + + if err := c.Manager.AddChartRepo(cr); err != nil { + httputil.BadRequest(w, r, err) + return nil + } + + util.LogHandlerExitWithText(handler, w, "added", http.StatusOK) + return nil +} + +func removeChartRepoHandlerFunc(w http.ResponseWriter, r *http.Request, c *router.Context) error { + handler := "manager: remove chart repository" + util.LogHandlerEntry(handler, r) + URL, err := pos(w, r, 2) + if err != nil { + return err + } + + err = c.Manager.RemoveChartRepo(URL) + if err != nil { + return err + } + + util.LogHandlerExitWithText(handler, w, "removed", http.StatusOK) + return nil +} diff --git a/cmd/manager/chartrepos_test.go b/cmd/manager/chartrepos_test.go index 0eaed403a..c9df699b3 100644 --- a/cmd/manager/chartrepos_test.go +++ b/cmd/manager/chartrepos_test.go @@ -17,19 +17,158 @@ limitations under the License. package main import ( + "github.com/kubernetes/helm/pkg/repo" + + "bytes" + "encoding/json" + "fmt" + "io" "net/http" + "net/url" "testing" ) -func TestListChartRepositories(t *testing.T) { +var ( + // TestRepoURL = "gs://kubernetes-charts-testing" + TestRepoURL = "foo" + TestChartName = "frobnitz-0.0.1.tgz" + TestRepoType = string(repo.GCSRepoType) + TestRepoFormat = string(repo.GCSRepoFormat) + TestRepoCredentialName = "default" +) + +func TestListChartRepos(t *testing.T) { c := stubContext() s := httpHarness(c, "GET /repositories", listChartReposHandlerFunc) defer s.Close() - res, err := http.Get(s.URL + "/repositories") + URL := getTestURL(t, s.URL, "", "") + res, err := http.Get(URL) + if err != nil { + t.Fatalf("Failed GET: %s", err) + } + + if res.StatusCode != http.StatusOK { + t.Errorf("Expected status %d, got %d", http.StatusOK, res.StatusCode) + } +} + +func TestGetChartRepo(t *testing.T) { + c := stubContext() + s := httpHarness(c, "GET /repositories/*", getChartRepoHandlerFunc) + defer s.Close() + + URL := getTestURL(t, s.URL, url.QueryEscape(TestRepoURL), "") + res, err := http.Get(URL) + if err != nil { + t.Fatalf("Failed GET: %s", err) + } + + if res.StatusCode != http.StatusOK { + t.Errorf("Expected status %d, got %d", http.StatusOK, res.StatusCode) + } +} + +func TestListRepoCharts(t *testing.T) { + c := stubContext() + s := httpHarness(c, "GET /repositories/*/charts", listRepoChartsHandlerFunc) + defer s.Close() + + URL := getTestURL(t, s.URL, url.QueryEscape(TestRepoURL), "charts") + res, err := http.Get(URL) if err != nil { - t.Errorf("Failed GET: %s", err) - } else if res.StatusCode != http.StatusOK { + t.Fatalf("Failed GET: %s", err) + } + + if res.StatusCode != http.StatusOK { t.Errorf("Expected status %d, got %d", http.StatusOK, res.StatusCode) } } + +func TestGetRepoChart(t *testing.T) { + c := stubContext() + s := httpHarness(c, "GET /repositories/*/charts/*", getRepoChartHandlerFunc) + defer s.Close() + + chartURL := fmt.Sprintf("charts/%s", TestChartName) + URL := getTestURL(t, s.URL, url.QueryEscape(TestRepoURL), chartURL) + res, err := http.Get(URL) + if err != nil { + t.Fatalf("Failed GET: %s", err) + } + + if res.StatusCode != http.StatusOK { + t.Errorf("Expected status %d, got %d", http.StatusOK, res.StatusCode) + } +} + +func TestAddChartRepo(t *testing.T) { + c := stubContext() + s := httpHarness(c, "POST /repositories", addChartRepoHandlerFunc) + defer s.Close() + + URL := getTestURL(t, s.URL, "", "") + body := getTestRepo(t, URL) + res, err := http.Post(URL, "application/json", body) + if err != nil { + t.Fatalf("Failed POST: %s", err) + } + + if res.StatusCode != http.StatusOK { + t.Errorf("Expected status %d, got %d", http.StatusOK, res.StatusCode) + } +} + +func TestRemoveChartRepo(t *testing.T) { + c := stubContext() + s := httpHarness(c, "DELETE /repositories/*", removeChartRepoHandlerFunc) + defer s.Close() + + URL := getTestURL(t, s.URL, url.QueryEscape(TestRepoURL), "") + req, err := http.NewRequest("DELETE", URL, nil) + if err != nil { + t.Fatalf("Cannot create DELETE request: %s", err) + } + + res, err := http.DefaultClient.Do(req) + if err != nil { + t.Fatalf("Failed DELETE: %s", err) + } + + defer res.Body.Close() + if res.StatusCode != http.StatusOK { + t.Errorf("Expected status %d, got %d", http.StatusOK, res.StatusCode) + } +} + +func getTestRepo(t *testing.T, URL string) io.Reader { + tr, err := repo.NewRepo(URL, TestRepoCredentialName, TestRepoFormat, TestRepoType) + if err != nil { + t.Fatalf("Cannot create test repository: %s", err) + } + + trb, err := json.Marshal(&tr) + if err != nil { + t.Fatalf("Cannot marshal test repository: %s", err) + } + + return bytes.NewReader(trb) +} + +func getTestURL(t *testing.T, baseURL, repoURL, chartURL string) string { + URL := fmt.Sprintf("%s/repositories", baseURL) + if repoURL != "" { + URL = fmt.Sprintf("%s/%s", URL, repoURL) + } + + if chartURL != "" { + URL = fmt.Sprintf("%s/%s", URL, chartURL) + } + + u, err := url.Parse(URL) + if err != nil { + t.Fatalf("cannot parse test URL %s: %s", URL, err) + } + + return u.String() +} diff --git a/pkg/repo/gcs_repo.go b/pkg/repo/gcs_repo.go index 8209fd7f5..10880a3eb 100644 --- a/pkg/repo/gcs_repo.go +++ b/pkg/repo/gcs_repo.go @@ -59,7 +59,7 @@ type GCSRepo struct { } // NewPublicGCSRepo creates a new an IStorageRepo for the public GCS repository. -func NewPublicGCSRepo(httpClient *http.Client) (IStorageRepo, error) { +func NewPublicGCSRepo(httpClient *http.Client) (*GCSRepo, error) { return NewGCSRepo(GCSPublicRepoURL, "", GCSPublicRepoBucket, nil) } From acfc6054806e9284b861aebf8955c0c90f6d2214 Mon Sep 17 00:00:00 2001 From: jackgr Date: Sun, 27 Mar 2016 16:37:29 -0700 Subject: [PATCH 2/6] Disambiguate method names --- cmd/manager/chartrepos.go | 44 ++++------------------------------ cmd/manager/manager/manager.go | 24 +++++++++---------- cmd/manager/testutil.go | 8 +++---- 3 files changed, 20 insertions(+), 56 deletions(-) diff --git a/cmd/manager/chartrepos.go b/cmd/manager/chartrepos.go index 55ea07f34..64ae8ddd8 100644 --- a/cmd/manager/chartrepos.go +++ b/cmd/manager/chartrepos.go @@ -39,7 +39,7 @@ func registerChartRepoRoutes(c *router.Context, h *router.Handler) { func listChartReposHandlerFunc(w http.ResponseWriter, r *http.Request, c *router.Context) error { handler := "manager: list chart repositories" - repos, err := c.Manager.ListChartRepos() + repos, err := c.Manager.ListRepos() if err != nil { return err } @@ -58,7 +58,7 @@ func addChartRepoHandlerFunc(w http.ResponseWriter, r *http.Request, c *router.C return nil } - if err := c.Manager.AddChartRepo(cr); err != nil { + if err := c.Manager.AddRepo(cr); err != nil { httputil.BadRequest(w, r, err) return nil } @@ -77,7 +77,7 @@ func removeChartRepoHandlerFunc(w http.ResponseWriter, r *http.Request, c *route return err } - err = c.Manager.RemoveChartRepo(name) + err = c.Manager.RemoveRepo(name) if err != nil { return err } @@ -95,7 +95,7 @@ func getChartRepoHandlerFunc(w http.ResponseWriter, r *http.Request, c *router.C return err } - cr, err := c.Manager.GetChartRepo(repoURL) + cr, err := c.Manager.GetRepo(repoURL) if err != nil { httputil.BadRequest(w, r, err) return nil @@ -159,39 +159,3 @@ func getRepoChartHandlerFunc(w http.ResponseWriter, r *http.Request, c *router.C util.LogHandlerExitWithJSON(handler, w, repoChart, http.StatusOK) return nil } - -func addChartRepoHandlerFunc(w http.ResponseWriter, r *http.Request, c *router.Context) error { - handler := "manager: add chart repository" - util.LogHandlerEntry(handler, r) - defer r.Body.Close() - cr := &repo.Repo{} - if err := httputil.Decode(w, r, cr); err != nil { - httputil.BadRequest(w, r, err) - return nil - } - - if err := c.Manager.AddChartRepo(cr); err != nil { - httputil.BadRequest(w, r, err) - return nil - } - - util.LogHandlerExitWithText(handler, w, "added", http.StatusOK) - return nil -} - -func removeChartRepoHandlerFunc(w http.ResponseWriter, r *http.Request, c *router.Context) error { - handler := "manager: remove chart repository" - util.LogHandlerEntry(handler, r) - URL, err := pos(w, r, 2) - if err != nil { - return err - } - - err = c.Manager.RemoveChartRepo(URL) - if err != nil { - return err - } - - util.LogHandlerExitWithText(handler, w, "removed", http.StatusOK) - return nil -} diff --git a/cmd/manager/manager/manager.go b/cmd/manager/manager/manager.go index 6649738db..dc07c0d2e 100644 --- a/cmd/manager/manager/manager.go +++ b/cmd/manager/manager/manager.go @@ -58,10 +58,10 @@ type Manager interface { GetCredential(name string) (*repo.Credential, error) // Chart Repositories - ListChartRepos() (map[string]string, error) - AddChartRepo(addition repo.IRepo) error - RemoveChartRepo(name string) error - GetChartRepo(URL string) (repo.IRepo, error) + ListRepos() (map[string]string, error) + AddRepo(addition repo.IRepo) error + RemoveRepo(name string) error + GetRepo(URL string) (repo.IRepo, error) } type manager struct { @@ -366,18 +366,18 @@ func (m *manager) GetChart(reference string) (*chart.Chart, error) { return c, nil } -// ListChartRepos returns the list of available chart repository URLs -func (m *manager) ListChartRepos() (map[string]string, error) { +// ListRepos returns the list of available repository URLs +func (m *manager) ListRepos() (map[string]string, error) { return m.service.ListRepos() } -// AddChartRepo adds a chart repository to the list -func (m *manager) AddChartRepo(addition repo.IRepo) error { +// AddRepo adds a repository to the list +func (m *manager) AddRepo(addition repo.IRepo) error { return m.service.CreateRepo(addition) } -// RemoveChartRepo removes a chart repository from the list by URL -func (m *manager) RemoveChartRepo(name string) error { +// RemoveRepo removes a repository from the list by URL +func (m *manager) RemoveRepo(name string) error { url, err := m.service.GetRepoURLByName(name) if err != nil { return err @@ -385,8 +385,8 @@ func (m *manager) RemoveChartRepo(name string) error { return m.service.DeleteRepo(url) } -// GetChartRepo returns the chart repository with the given URL -func (m *manager) GetChartRepo(URL string) (repo.IRepo, error) { +// GetRepo returns the repository with the given URL +func (m *manager) GetRepo(URL string) (repo.IRepo, error) { return m.service.GetRepoByURL(URL) } diff --git a/cmd/manager/testutil.go b/cmd/manager/testutil.go index 86db0e4f3..eb532c6e5 100644 --- a/cmd/manager/testutil.go +++ b/cmd/manager/testutil.go @@ -119,19 +119,19 @@ func (m *mockManager) GetChart(chartName string) (*chart.Chart, error) { return nil, nil } -func (m *mockManager) AddChartRepo(addition repo.IRepo) error { +func (m *mockManager) AddRepo(addition repo.IRepo) error { return nil } -func (m *mockManager) ListChartRepos() (map[string]string, error) { +func (m *mockManager) ListRepos() (map[string]string, error) { return map[string]string{}, nil } -func (m *mockManager) RemoveChartRepo(name string) error { +func (m *mockManager) RemoveRepo(name string) error { return nil } -func (m *mockManager) GetChartRepo(URL string) (repo.IRepo, error) { +func (m *mockManager) GetRepo(URL string) (repo.IRepo, error) { return nil, nil } From 103145cc9d27df0f0015f68bdee734d91b752ea6 Mon Sep 17 00:00:00 2001 From: jackgr Date: Sun, 27 Mar 2016 17:13:15 -0700 Subject: [PATCH 3/6] Make all repo methods name based. --- cmd/manager/manager/manager.go | 40 ++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/cmd/manager/manager/manager.go b/cmd/manager/manager/manager.go index dc07c0d2e..87bae259e 100644 --- a/cmd/manager/manager/manager.go +++ b/cmd/manager/manager/manager.go @@ -50,8 +50,8 @@ type Manager interface { GetChart(chartName string) (*chart.Chart, error) // Repo Charts - ListRepoCharts(repoURL string, regex *regexp.Regexp) ([]string, error) - GetChartForRepo(repoURL, chartName string) (*chart.Chart, error) + ListRepoCharts(repoName string, regex *regexp.Regexp) ([]string, error) + GetChartForRepo(repoName, chartName string) (*chart.Chart, error) // Credentials CreateCredential(name string, c *repo.Credential) error @@ -60,8 +60,8 @@ type Manager interface { // Chart Repositories ListRepos() (map[string]string, error) AddRepo(addition repo.IRepo) error - RemoveRepo(name string) error - GetRepo(URL string) (repo.IRepo, error) + RemoveRepo(repoName string) error + GetRepo(repoName string) (repo.IRepo, error) } type manager struct { @@ -377,17 +377,23 @@ func (m *manager) AddRepo(addition repo.IRepo) error { } // RemoveRepo removes a repository from the list by URL -func (m *manager) RemoveRepo(name string) error { - url, err := m.service.GetRepoURLByName(name) +func (m *manager) RemoveRepo(repoName string) error { + repoURL, err := m.service.GetRepoURLByName(repoName) if err != nil { return err } - return m.service.DeleteRepo(url) + + return m.service.DeleteRepo(repoURL) } // GetRepo returns the repository with the given URL -func (m *manager) GetRepo(URL string) (repo.IRepo, error) { - return m.service.GetRepoByURL(URL) +func (m *manager) GetRepo(repoName string) (repo.IRepo, error) { + repoURL, err := m.service.GetRepoURLByName(repoName) + if err != nil { + return nil, err + } + + return m.service.GetRepoByURL(repoURL) } func generateManifestName() string { @@ -412,10 +418,15 @@ func getResourceErrors(c *common.Configuration) []string { return errs } -// ListRepoCharts lists charts in a given repository whose URLs +// ListRepoCharts lists charts in a given repository whose names // conform to the supplied regular expression, or all charts, if the regular // expression is nil. -func (m *manager) ListRepoCharts(repoURL string, regex *regexp.Regexp) ([]string, error) { +func (m *manager) ListRepoCharts(repoName string, regex *regexp.Regexp) ([]string, error) { + repoURL, err := m.service.GetRepoURLByName(repoName) + if err != nil { + return nil, err + } + r, err := m.repoProvider.GetRepoByURL(repoURL) if err != nil { return nil, err @@ -425,7 +436,12 @@ func (m *manager) ListRepoCharts(repoURL string, regex *regexp.Regexp) ([]string } // GetChartForRepo returns a chart by name from a given repository. -func (m *manager) GetChartForRepo(repoURL, chartName string) (*chart.Chart, error) { +func (m *manager) GetChartForRepo(repoName, chartName string) (*chart.Chart, error) { + repoURL, err := m.service.GetRepoURLByName(repoName) + if err != nil { + return nil, err + } + r, err := m.repoProvider.GetRepoByURL(repoURL) if err != nil { return nil, err From 541fe062c656cd118056ace76c2b2c1e4d2ba976 Mon Sep 17 00:00:00 2001 From: jackgr Date: Sun, 27 Mar 2016 17:13:40 -0700 Subject: [PATCH 4/6] Clean up manager test utility --- cmd/manager/testutil.go | 46 ++++++++++++++--------------------------- 1 file changed, 16 insertions(+), 30 deletions(-) diff --git a/cmd/manager/testutil.go b/cmd/manager/testutil.go index eb532c6e5..059604277 100644 --- a/cmd/manager/testutil.go +++ b/cmd/manager/testutil.go @@ -112,54 +112,40 @@ func (m *mockManager) GetRepoForChart(chartName string) (string, error) { } func (m *mockManager) GetMetadataForChart(chartName string) (*chart.Chartfile, error) { - return nil, nil + return &chart.Chartfile{}, nil } func (m *mockManager) GetChart(chartName string) (*chart.Chart, error) { - return nil, nil + return &chart.Chart{}, nil } -func (m *mockManager) AddRepo(addition repo.IRepo) error { - return nil +func (m *mockManager) ListRepoCharts(repoName string, regex *regexp.Regexp) ([]string, error) { + return []string{}, nil } -func (m *mockManager) ListRepos() (map[string]string, error) { - return map[string]string{}, nil +func (m *mockManager) GetChartForRepo(repoName, chartName string) (*chart.Chart, error) { + return &chart.Chart{}, nil } -func (m *mockManager) RemoveRepo(name string) error { +func (m *mockManager) CreateCredential(name string, c *repo.Credential) error { return nil } - -func (m *mockManager) GetRepo(URL string) (repo.IRepo, error) { - return nil, nil +func (m *mockManager) GetCredential(name string) (*repo.Credential, error) { + return &repo.Credential{}, nil } -func (m *mockManager) ListRepos() ([]*repo.Repo, error) { - return []*repo.Repo{}, nil +func (m *mockManager) ListRepos() (map[string]string, error) { + return map[string]string{}, nil } -func (m *mockManager) CreateRepo(pr *repo.Repo) error { - return nil -} -func (m *mockManager) GetRepo(name string) (*repo.Repo, error) { - return &repo.Repo{}, nil -} -func (m *mockManager) DeleteRepo(name string) error { +func (m *mockManager) AddRepo(addition repo.IRepo) error { return nil } -func (m *mockManager) ListRepoCharts(repoName string, regex *regexp.Regexp) ([]string, error) { - return []string{}, nil -} - -func (m *mockManager) GetChartForRepo(repoName, chartName string) (*chart.Chart, error) { - return nil, nil -} - -func (m *mockManager) CreateCredential(name string, c *repo.Credential) error { +func (m *mockManager) RemoveRepo(name string) error { return nil } -func (m *mockManager) GetCredential(name string) (*repo.Credential, error) { - return &repo.Credential{}, nil + +func (m *mockManager) GetRepo(name string) (repo.IRepo, error) { + return &repo.Repo{}, nil } From 403720516dd2bd35d4aeb9d37bd34202aac15b5d Mon Sep 17 00:00:00 2001 From: jackgr Date: Sun, 27 Mar 2016 17:14:06 -0700 Subject: [PATCH 5/6] Make repo routes name based --- cmd/manager/chartrepos_test.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/cmd/manager/chartrepos_test.go b/cmd/manager/chartrepos_test.go index c9df699b3..4662bac6d 100644 --- a/cmd/manager/chartrepos_test.go +++ b/cmd/manager/chartrepos_test.go @@ -29,8 +29,8 @@ import ( ) var ( - // TestRepoURL = "gs://kubernetes-charts-testing" - TestRepoURL = "foo" + TestRepoBucket = "kubernetes-charts-testing" + TestRepoURL = "gs://" + TestRepoBucket TestChartName = "frobnitz-0.0.1.tgz" TestRepoType = string(repo.GCSRepoType) TestRepoFormat = string(repo.GCSRepoFormat) @@ -58,7 +58,7 @@ func TestGetChartRepo(t *testing.T) { s := httpHarness(c, "GET /repositories/*", getChartRepoHandlerFunc) defer s.Close() - URL := getTestURL(t, s.URL, url.QueryEscape(TestRepoURL), "") + URL := getTestURL(t, s.URL, TestRepoBucket, "") res, err := http.Get(URL) if err != nil { t.Fatalf("Failed GET: %s", err) @@ -74,7 +74,7 @@ func TestListRepoCharts(t *testing.T) { s := httpHarness(c, "GET /repositories/*/charts", listRepoChartsHandlerFunc) defer s.Close() - URL := getTestURL(t, s.URL, url.QueryEscape(TestRepoURL), "charts") + URL := getTestURL(t, s.URL, TestRepoBucket, "charts") res, err := http.Get(URL) if err != nil { t.Fatalf("Failed GET: %s", err) @@ -91,7 +91,7 @@ func TestGetRepoChart(t *testing.T) { defer s.Close() chartURL := fmt.Sprintf("charts/%s", TestChartName) - URL := getTestURL(t, s.URL, url.QueryEscape(TestRepoURL), chartURL) + URL := getTestURL(t, s.URL, TestRepoBucket, chartURL) res, err := http.Get(URL) if err != nil { t.Fatalf("Failed GET: %s", err) @@ -114,7 +114,7 @@ func TestAddChartRepo(t *testing.T) { t.Fatalf("Failed POST: %s", err) } - if res.StatusCode != http.StatusOK { + if res.StatusCode != http.StatusCreated { t.Errorf("Expected status %d, got %d", http.StatusOK, res.StatusCode) } } @@ -124,7 +124,7 @@ func TestRemoveChartRepo(t *testing.T) { s := httpHarness(c, "DELETE /repositories/*", removeChartRepoHandlerFunc) defer s.Close() - URL := getTestURL(t, s.URL, url.QueryEscape(TestRepoURL), "") + URL := getTestURL(t, s.URL, TestRepoBucket, "") req, err := http.NewRequest("DELETE", URL, nil) if err != nil { t.Fatalf("Cannot create DELETE request: %s", err) @@ -142,7 +142,7 @@ func TestRemoveChartRepo(t *testing.T) { } func getTestRepo(t *testing.T, URL string) io.Reader { - tr, err := repo.NewRepo(URL, TestRepoCredentialName, TestRepoFormat, TestRepoType) + tr, err := repo.NewRepo(URL, TestRepoCredentialName, TestRepoBucket, TestRepoFormat, TestRepoType) if err != nil { t.Fatalf("Cannot create test repository: %s", err) } From 73ff6768f29ff5e534c591ed34d8ba3dd297e565 Mon Sep 17 00:00:00 2001 From: jackgr Date: Sun, 27 Mar 2016 17:14:21 -0700 Subject: [PATCH 6/6] Fix merge bug --- pkg/repo/gcs_repo.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/repo/gcs_repo.go b/pkg/repo/gcs_repo.go index 10880a3eb..26f285409 100644 --- a/pkg/repo/gcs_repo.go +++ b/pkg/repo/gcs_repo.go @@ -64,7 +64,7 @@ func NewPublicGCSRepo(httpClient *http.Client) (*GCSRepo, error) { } // NewGCSRepo creates a new IStorageRepo for a given GCS repository. -func NewGCSRepo(URL, credentialName, repoName string, httpClient *http.Client) (IStorageRepo, error) { +func NewGCSRepo(URL, credentialName, repoName string, httpClient *http.Client) (*GCSRepo, error) { r, err := newRepo(URL, credentialName, repoName, GCSRepoFormat, GCSRepoType) if err != nil { return nil, err