From ea627f7ec5c11cebcac8e6259c83e925f9ec19d0 Mon Sep 17 00:00:00 2001 From: Vincent Boutour Date: Sun, 2 May 2021 00:30:47 +0200 Subject: [PATCH] refactor: Refactoring helm fetch for multiple charts in the same index Signed-off-by: Vincent Boutour --- pkg/helm/helm.go | 69 ++++++++++++++++++++--------------- pkg/helm/helmtest/helmtest.go | 16 ++++++++ 2 files changed, 56 insertions(+), 29 deletions(-) diff --git a/pkg/helm/helm.go b/pkg/helm/helm.go index 1a640247..28152089 100644 --- a/pkg/helm/helm.go +++ b/pkg/helm/helm.go @@ -7,6 +7,7 @@ import ( "io" "strings" + "github.com/ViBiOh/httputils/v4/pkg/logger" "github.com/ViBiOh/httputils/v4/pkg/request" "github.com/ViBiOh/ketchup/pkg/model" "github.com/ViBiOh/ketchup/pkg/semver" @@ -28,6 +29,7 @@ type chart struct { // App of package type App interface { LatestVersions(string, []string) (map[string]semver.Version, error) + FetchIndex(string, map[string][]string) (map[string]map[string]semver.Version, error) } type app struct{} @@ -37,20 +39,48 @@ func New() App { return app{} } -func parseHelmIndex(content io.Reader) (charts, error) { - decoder := yaml.NewDecoder(content) +func (a app) FetchIndex(url string, chartsPatterns map[string][]string) (map[string]map[string]semver.Version, error) { + resp, err := request.New().Get(fmt.Sprintf("%s/%s", url, indexName)).Send(context.Background(), nil) + if err != nil { + return nil, fmt.Errorf("unable to request repository: %w", err) + } + + defer func() { + if err := resp.Body.Close(); err != nil { + logger.Error("unable to close response body: %s", err) + } + }() + var index charts + if err := yaml.NewDecoder(resp.Body).Decode(&index); err != nil && err != io.EOF { + return nil, fmt.Errorf("unable to parse yaml index: %s", err) + } - for { - err := decoder.Decode(&index) + output := make(map[string]map[string]semver.Version, len(index.Entries)) + for key, charts := range index.Entries { + patterns, ok := chartsPatterns[key] + if !ok { + continue + } + + versions, compiledPatterns, err := model.PreparePatternMatching(patterns) if err != nil { - if err == io.EOF { - return index, nil + return nil, fmt.Errorf("unable to prepare pattern matching for `%s`: %s", key, err) + } + + for _, chart := range charts { + chartVersion, err := semver.Parse(chart.Version) + if err != nil { + continue } - return index, fmt.Errorf("unable to parse yaml index: %s", err) + model.CheckPatternsMatching(versions, compiledPatterns, chartVersion) } + + output[key] = versions } + + return output, nil } func (a app) LatestVersions(repository string, patterns []string) (map[string]semver.Version, error) { @@ -59,34 +89,15 @@ func (a app) LatestVersions(repository string, patterns []string) (map[string]se return nil, errors.New("invalid name for helm chart") } - resp, err := request.New().Get(fmt.Sprintf("%s/%s", parts[1], indexName)).Send(context.Background(), nil) - if err != nil { - return nil, fmt.Errorf("unable to request repository: %w", err) - } - - index, err := parseHelmIndex(resp.Body) + index, err := a.FetchIndex(parts[1], map[string][]string{repository: patterns}) if err != nil { return nil, err } - charts, ok := index.Entries[parts[0]] + charts, ok := index[parts[0]] if !ok { return nil, fmt.Errorf("no chart `%s` in repository", parts[0]) } - versions, compiledPatterns, err := model.PreparePatternMatching(patterns) - if err != nil { - return nil, fmt.Errorf("unable to prepare pattern matching: %s", err) - } - - for _, chart := range charts { - chartVersion, err := semver.Parse(chart.Version) - if err != nil { - continue - } - - model.CheckPatternsMatching(versions, compiledPatterns, chartVersion) - } - - return versions, nil + return charts, nil } diff --git a/pkg/helm/helmtest/helmtest.go b/pkg/helm/helmtest/helmtest.go index 5cfcf4e4..6d9c42dc 100644 --- a/pkg/helm/helmtest/helmtest.go +++ b/pkg/helm/helmtest/helmtest.go @@ -11,6 +11,9 @@ var _ helm.App = &App{} type App struct { latestVersions map[string]semver.Version latestVersionsErr error + + fetchIndex map[string]map[string]semver.Version + fetchIndexErr error } // New creates mock @@ -30,3 +33,16 @@ func (a *App) SetLatestVersions(latestVersions map[string]semver.Version, err er func (a App) LatestVersions(_ string, _ []string) (map[string]semver.Version, error) { return a.latestVersions, a.latestVersionsErr } + +// SetFetchIndex mock +func (a *App) SetFetchIndex(charts map[string]map[string]semver.Version, err error) *App { + a.fetchIndex = charts + a.fetchIndexErr = err + + return a +} + +// FetchIndex mock +func (a App) FetchIndex(_ string, _ map[string][]string) (map[string]map[string]semver.Version, error) { + return a.fetchIndex, a.fetchIndexErr +}