This repository has been archived by the owner on Jul 22, 2019. It is now read-only.
/
chart.go
131 lines (113 loc) · 2.97 KB
/
chart.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package chart
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
"strings"
"github.com/ghodss/yaml"
"k8s.io/helm/pkg/proto/hapi/chart"
"k8s.io/helm/pkg/repo"
)
// HTTPClient Interface to perform HTTP requests
type HTTPClient interface {
Do(req *http.Request) (*http.Response, error)
}
func getReq(rawURL, authHeader string) (*http.Request, error) {
parsedURL, err := url.ParseRequestURI(rawURL)
if err != nil {
return nil, err
}
req, err := http.NewRequest("GET", parsedURL.String(), nil)
if err != nil {
return nil, err
}
if len(authHeader) > 0 {
req.Header.Set("Authorization", authHeader)
}
return req, nil
}
func readResponseBody(res *http.Response) ([]byte, error) {
if res != nil {
defer res.Body.Close()
}
if res.StatusCode != http.StatusOK {
return nil, fmt.Errorf("chart download request failed")
}
body, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}
return body, nil
}
func parseIndex(data []byte) (*repo.IndexFile, error) {
index := &repo.IndexFile{}
err := yaml.Unmarshal(data, index)
if err != nil {
return index, err
}
index.SortEntries()
return index, nil
}
// FetchRepoIndex returns a Helm repository
func FetchRepoIndex(netClient *HTTPClient, repoURL string, authHeader string) (*repo.IndexFile, error) {
req, err := getReq(repoURL, authHeader)
if err != nil {
return nil, err
}
res, err := (*netClient).Do(req)
if err != nil {
return nil, err
}
data, err := readResponseBody(res)
if err != nil {
return nil, err
}
return parseIndex(data)
}
func resolveChartURL(index, chart string) (string, error) {
indexURL, err := url.Parse(strings.TrimSpace(index))
if err != nil {
return "", err
}
chartURL, err := indexURL.Parse(strings.TrimSpace(chart))
if err != nil {
return "", err
}
return chartURL.String(), nil
}
// FindChartInRepoIndex returns the URL of a chart given a Helm repository and its name and version
func FindChartInRepoIndex(repoIndex *repo.IndexFile, repoURL, chartName, chartVersion string) (string, error) {
errMsg := fmt.Sprintf("chart %q", chartName)
if chartVersion != "" {
errMsg = fmt.Sprintf("%s version %q", errMsg, chartVersion)
}
cv, err := repoIndex.Get(chartName, chartVersion)
if err != nil {
return "", fmt.Errorf("%s not found in repository", errMsg)
}
if len(cv.URLs) == 0 {
return "", fmt.Errorf("%s has no downloadable URLs", errMsg)
}
return resolveChartURL(repoURL, cv.URLs[0])
}
// LoadChart should return a Chart struct from an IOReader
type LoadChart func(in io.Reader) (*chart.Chart, error)
// FetchChart returns the Chart content given an URL and the auth header if needed
func FetchChart(netClient *HTTPClient, chartURL, authHeader string, load LoadChart) (*chart.Chart, error) {
req, err := getReq(chartURL, authHeader)
if err != nil {
return nil, err
}
res, err := (*netClient).Do(req)
if err != nil {
return nil, err
}
data, err := readResponseBody(res)
if err != nil {
return nil, err
}
return load(bytes.NewReader(data))
}