Skip to content

Commit

Permalink
refactor: Refactoring helm fetch for multiple charts in the same index
Browse files Browse the repository at this point in the history
Signed-off-by: Vincent Boutour <bob@vibioh.fr>
  • Loading branch information
ViBiOh committed May 1, 2021
1 parent 602eddc commit ea627f7
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 29 deletions.
69 changes: 40 additions & 29 deletions pkg/helm/helm.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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{}
Expand All @@ -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) {
Expand All @@ -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
}
16 changes: 16 additions & 0 deletions pkg/helm/helmtest/helmtest.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
}

0 comments on commit ea627f7

Please sign in to comment.