Skip to content

Commit 4cffd0d

Browse files
committed
Add func to get images required for a chart
1 parent 2ae3c07 commit 4cffd0d

File tree

4 files changed

+83
-249
lines changed

4 files changed

+83
-249
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ require (
1313
golang.org/x/net v0.0.0-20200707034311-ab3426394381 // indirect
1414
golang.org/x/sys v0.0.0-20200922070232-aee5d888a860 // indirect
1515
gopkg.in/yaml.v2 v2.3.0
16+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c
1617
helm.sh/helm/v3 v3.3.0
1718
rsc.io/letsencrypt v0.0.3 // indirect
1819
)

go.sum

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -918,6 +918,7 @@ gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
918918
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
919919
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
920920
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
921+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
921922
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
922923
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
923924
helm.sh/helm/v3 v3.3.0 h1:7BUpW5NI1pauKDnIh0ju53pNc3Ra/UyqqBr0b5OgBwY=

helm/repo.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,21 @@ import (
1818
"gopkg.in/yaml.v2"
1919

2020
"helm.sh/helm/v3/pkg/action"
21+
"helm.sh/helm/v3/pkg/chart/loader"
22+
"helm.sh/helm/v3/pkg/chartutil"
2123
"helm.sh/helm/v3/pkg/cli"
2224
"helm.sh/helm/v3/pkg/downloader"
2325
"helm.sh/helm/v3/pkg/getter"
2426
"helm.sh/helm/v3/pkg/repo"
2527
)
2628

29+
type imageValue struct {
30+
Registry string
31+
Name string
32+
Repository string
33+
Tag string
34+
}
35+
2736
// RepoAdd adds repo with given name and url
2837
func RepoAdd(name, url string) {
2938

@@ -159,3 +168,65 @@ func debug(format string, v ...interface{}) {
159168
format = fmt.Sprintf("[debug] %s\n", format)
160169
log.Output(2, fmt.Sprintf(format, v...))
161170
}
171+
172+
// GetChartImages take a chart in tgz format and return an image list
173+
func GetChartImages(chartPath string) ([]string, error) {
174+
175+
chart, err := loader.Load(chartPath)
176+
if err != nil {
177+
fmt.Printf("Error when loading chart.\n")
178+
return nil, err
179+
}
180+
181+
cvals, err := chartutil.CoalesceValues(chart, nil)
182+
if err != nil {
183+
fmt.Printf("ERR CoalesceValues.\n")
184+
return nil, err
185+
}
186+
187+
imageList, err := GetChartImagesFromValues(cvals)
188+
if err != nil {
189+
return nil, err
190+
}
191+
return imageList, nil
192+
}
193+
194+
// GetChartImagesFromValues take a map of string corresponding to a values.yaml an return an image list
195+
func GetChartImagesFromValues(values map[string]interface{}) ([]string, error) {
196+
var imgList []string
197+
for k, v := range values {
198+
if k == "image" {
199+
if _, ok := v.(map[string]interface{}); ok {
200+
yml, err := yaml.Marshal(v)
201+
if err != nil {
202+
return nil, err
203+
}
204+
205+
var img imageValue
206+
err = yaml.Unmarshal(yml, &img)
207+
if err != nil {
208+
return nil, err
209+
}
210+
211+
imgStr := fmt.Sprintf("%s:%s\n", img.Repository, img.Tag)
212+
if img.Repository == "" {
213+
imgStr = fmt.Sprintf("%s:%s\n", img.Name, img.Tag)
214+
}
215+
216+
if img.Registry != "" {
217+
imgStr = fmt.Sprintf("%s/%s", img.Registry, imgStr)
218+
}
219+
imgList = append(imgList, imgStr)
220+
}
221+
} else {
222+
if _, ok := v.(map[string]interface{}); ok {
223+
il, err := GetChartImagesFromValues(v.(map[string]interface{}))
224+
if err != nil {
225+
return nil, err
226+
}
227+
imgList = append(imgList, il...)
228+
}
229+
}
230+
}
231+
return imgList, nil
232+
}

main.go

Lines changed: 10 additions & 249 deletions
Original file line numberDiff line numberDiff line change
@@ -1,261 +1,22 @@
11
package main
22

33
import (
4-
"fmt"
5-
"rkd/helm"
4+
"os"
5+
"rkd/cmd"
66

7-
"gopkg.in/yaml.v2"
8-
"helm.sh/helm/v3/pkg/chart/loader"
9-
"helm.sh/helm/v3/pkg/chartutil"
7+
"github.com/urfave/cli"
108
)
119

12-
var (
13-
rancherStableRepoURL = "https://releases.rancher.com/server-charts/stable"
14-
rancherLatestRepoURL = "https://releases.rancher.com/server-charts/latest"
15-
rancherStableRepoName = "rancher-stable"
16-
rancherLatestRepoName = "rancher-latest"
17-
rancherChartName = "rancher"
18-
19-
testChartName = "ceph-csi-rbd"
20-
testRepoName = "ceph-csi-rbd"
21-
testRepoURL = "https://ceph.github.io/csi-charts"
22-
)
23-
24-
type imageValue struct {
25-
name string
26-
repository string
27-
tag string
28-
}
29-
30-
type k8sYamlStruct struct {
31-
APIVersion string `json:"apiVersion" yaml:"apiVersion"`
32-
Kind string `json:"kind" yaml:"kind"`
33-
Metadata k8sYamlMetadata `json:"metadata" yaml:"metadata"`
34-
Spec k8sYamlSpec `json:"spec" yaml:"spec"`
35-
}
36-
37-
type k8sYamlMetadata struct {
38-
Namespace string
39-
Name string
40-
}
41-
42-
type k8sYamlSpec struct {
43-
Template k8sYamlTemplate
44-
}
45-
46-
type k8sYamlTemplate struct {
47-
Spec k8sYamlSpecTemplate
48-
}
49-
50-
type k8sYamlSpecTemplate struct {
51-
Containers []k8sYamlContrainer
52-
}
53-
54-
type k8sYamlContrainer struct {
55-
Name string
56-
Image string
57-
}
58-
5910
func main() {
6011

61-
///test
62-
helm.RepoAdd(testChartName, testRepoURL)
63-
helm.RepoUpdate()
64-
helm.DownloadChart(testRepoName, testChartName, "3.1.1", "./test")
65-
66-
chart, err := loader.Load("./test/gitlab-4.4.4.tgz")
67-
if err != nil {
68-
fmt.Printf("%s\n", err)
69-
}
70-
71-
cvals, err := chartutil.CoalesceValues(chart, nil)
72-
if err != nil {
73-
fmt.Printf("ERR CoalesceValues => %s\n", err)
74-
return
75-
}
76-
77-
getImage(cvals)
78-
79-
// charts := chart.Dependencies()
80-
// charts = append(charts, chart)
12+
app := cli.NewApp()
13+
app.Name = "rkd"
14+
app.Usage = "Rancher Kubernetes Downloader"
8115

82-
// fmt.Printf("%s\n", chart.Name())
83-
// fmt.Printf("%s\n", chart.AppVersion())
84-
85-
// options := chartutil.ReleaseOptions{
86-
// Name: "test-release",
87-
// Namespace: "default",
88-
// }
89-
90-
// for _, c := range charts {
91-
92-
// cValues := completMockData(c.Values)
93-
94-
// fmt.Printf("%s", cValues)
95-
96-
// valuesToRender, err := chartutil.ToRenderValues(c, cvals, options, nil)
97-
// if err != nil {
98-
// fmt.Printf("ERR ToRenderValues => %s\n", err)
99-
// return
100-
// }
101-
102-
// var e engine.Engine
103-
// e.LintMode = true
104-
105-
// renderedContentMap, err := e.Render(c, valuesToRender)
106-
// if err != nil {
107-
// fmt.Printf("ERR Render => %s\n", err)
108-
// return
109-
// }
110-
111-
// for _, template := range c.Templates {
112-
// fileName := template.Name
113-
114-
// // We only apply the following lint rules to yaml files
115-
// if filepath.Ext(fileName) != ".yaml" || filepath.Ext(fileName) == ".yml" {
116-
// continue
117-
// }
118-
119-
// renderedContent := renderedContentMap[path.Join(c.Name(), fileName)]
120-
// if strings.TrimSpace(renderedContent) != "" {
121-
// var yamlStruct k8sYamlStruct
122-
// // Even though K8sYamlStruct only defines a few fields, an error in any other
123-
// // key will be raised as well
124-
// err := yaml.Unmarshal([]byte(renderedContent), &yamlStruct)
125-
// if err != nil {
126-
// fmt.Printf("ERR yaml Unmarshal => %s\n", err)
127-
// return
128-
// }
129-
130-
// if !reflect.DeepEqual(yamlStruct.Spec, k8sYamlSpec{}) {
131-
// if !reflect.DeepEqual(yamlStruct.Spec.Template, k8sYamlTemplate{}) {
132-
// if !reflect.DeepEqual(yamlStruct.Spec.Template.Spec, k8sYamlSpecTemplate{}) {
133-
// if len(yamlStruct.Spec.Template.Spec.Containers) > 0 {
134-
// fmt.Printf("\n%s (%s)\n---\n", fileName, yamlStruct.Kind)
135-
// for _, c := range yamlStruct.Spec.Template.Spec.Containers {
136-
// fmt.Printf("%s,", c.Image)
137-
// }
138-
// }
139-
// }
140-
// }
141-
// }
142-
// fmt.Printf("\n")
143-
// }
144-
// }
145-
// }
146-
147-
/*
148-
for i, t := range chart.Templates {
149-
fmt.Printf("%d. %s\n", i, t.Name)
150-
151-
if t.Name == "templates/deployment.yaml" {
152-
//fmt.Printf("%s\n", t.Data)
153-
d, err := chartutil.ReadValues(t.Data)
154-
if err != nil {
155-
fmt.Printf("%s\n", err)
156-
}
157-
fmt.Printf("%s\n", d)
158-
}
159-
}*/
160-
///
161-
162-
// app := cli.NewApp()
163-
// app.Name = "rkd"
164-
// app.Usage = "Rancher Kubernetes Downloader"
165-
166-
// app.Commands = []cli.Command{
167-
// cmd.ListCommand(),
168-
// cmd.DownloadCommand(),
169-
// }
170-
171-
// app.Run(os.Args)
172-
}
173-
174-
func getImage(values map[string]interface{}) {
175-
for _, v := range values {
176-
switch v.(type) {
177-
// case string:
178-
// if k == "image" || k == "tag" || k == "repository" {
179-
// fmt.Printf("%s => %s\n", k, v)
180-
// }
181-
case map[string]interface{}:
182-
var imgObj imageValue
183-
yamlObj, err := yaml.Marshal(v)
184-
if err != nil {
185-
fmt.Printf("%s\n", err)
186-
continue
187-
}
188-
err = yaml.Unmarshal(yamlObj, &imgObj)
189-
if err != nil {
190-
fmt.Printf("%s\n", err)
191-
continue
192-
}
193-
if imgObj.name != "" && imgObj.tag != "" {
194-
fmt.Printf("%s:%s\n", imgObj.name, imgObj.tag)
195-
} else if imgObj.repository != "" && imgObj.tag != "" {
196-
fmt.Printf("%s:%s\n", imgObj.repository, imgObj.tag)
197-
} else {
198-
fmt.Printf("%s\n", imgObj)
199-
getImage(v.(map[string]interface{}))
200-
}
201-
}
16+
app.Commands = []cli.Command{
17+
cmd.ListCommand(),
18+
cmd.DownloadCommand(),
20219
}
203-
}
20420

205-
func completMockData(obj map[string]interface{}) map[string]interface{} {
206-
for k, v := range obj {
207-
switch v.(type) {
208-
case bool:
209-
obj[k] = true
210-
case string:
211-
if obj[k] == "" || obj[k] == nil {
212-
obj[k] = "a"
213-
}
214-
case float64:
215-
if obj[k] == nil {
216-
obj[k] = 0
217-
}
218-
case int:
219-
if obj[k] == nil {
220-
obj[k] = 0
221-
}
222-
case map[string]interface{}:
223-
obj[k] = completMockData(v.(map[string]interface{}))
224-
case nil:
225-
obj[k] = true
226-
case []interface{}:
227-
obj[k] = completMockSliceData(v.([]interface{}))
228-
default:
229-
fmt.Printf("================================> %T %s %s", v, k, v)
230-
}
231-
}
232-
return obj
233-
}
234-
235-
func completMockSliceData(obj []interface{}) []interface{} {
236-
for k, v := range obj {
237-
switch v.(type) {
238-
case bool:
239-
obj[k] = false
240-
case string:
241-
if obj[k] == "" || obj[k] == nil {
242-
obj[k] = "a"
243-
}
244-
case float64:
245-
if obj[k] == nil {
246-
obj[k] = 0
247-
}
248-
case int:
249-
if obj[k] == nil {
250-
obj[k] = 0
251-
}
252-
case map[string]interface{}:
253-
obj[k] = completMockData(v.(map[string]interface{}))
254-
case nil:
255-
obj[k] = "a"
256-
default:
257-
fmt.Printf("================================> %T", v)
258-
}
259-
}
260-
return obj
21+
app.Run(os.Args)
26122
}

0 commit comments

Comments
 (0)