blob: e56d5f2bb5926e31c7b4984ee8a8ab1bfbaf93b3 [file] [log] [blame]
giolekvad5a58c42020-05-07 22:18:35 +04001package appmanager
2
3import (
4 "errors"
5 "fmt"
6 "os/exec"
7 "strings"
8
9 "github.com/golang/glog"
10)
11
12type Unpacker interface {
13 Unpack(archive string,
14 namespace string,
15 releaseRame string,
16 values map[string]string) (map[string][]string, error)
17}
18
19type helmUnpacker struct {
20 helmBin string
21}
22
23func NewHelmUnpacker(helmBin string) Unpacker {
24 return &helmUnpacker{helmBin}
25}
26
27func (h *helmUnpacker) Unpack(
28 archive string,
29 namespace string,
30 releaseName string,
31 values map[string]string) (map[string][]string, error) {
32 cmd := h.generateHelmInstallCmd(archive, namespace, releaseName, values)
33 glog.Info(cmd.String())
34 var stdout strings.Builder
35 var stderr strings.Builder
36 cmd.Stdout = &stdout
37 cmd.Stderr = &stderr
38 err := cmd.Run()
39 if err != nil {
40 return nil, errors.New(stderr.String())
41 }
42 return extractTemplates(stdout.String())
43}
44
45func (h *helmUnpacker) generateHelmInstallCmd(
46 archive string,
47 namespace string,
48 releaseName string,
49 values map[string]string) *exec.Cmd {
50 cmd := exec.Command(h.helmBin)
51 cmd.Args = append(cmd.Args, "template")
52 cmd.Args = append(cmd.Args, fmt.Sprintf("--namespace=%s", namespace))
53 cmd.Args = append(cmd.Args, fmt.Sprintf("%s", releaseName))
54 cmd.Args = append(cmd.Args, fmt.Sprintf("%s", archive))
55 // TODO(giolekva): validate values
56 for key, value := range values {
57 cmd.Args = append(cmd.Args, fmt.Sprintf("--set=%s=%s", key, value))
58 }
59 return cmd
60}
61
62func extractTemplates(bundle string) (map[string][]string, error) {
63 items := strings.Split(bundle, "---")
64 temps := make(map[string][]string)
65 for _, item := range items {
66 if len(item) == 0 {
67 continue
68 }
69 tmp := strings.SplitN(item, "\n", 3)
70 if len(tmp) != 3 {
71 return nil, fmt.Errorf("Got invalid template: %s", item)
72 }
73 source := tmp[1]
74 glog.Info(source)
75 // if !strings.HasPrefix(source, "\n# Source: ") {
76 // return nil, fmt.Errorf("Got invalid source: %s", item)
77 // }
78 sourceItems := strings.Split(source, "/")
79 glog.Info(sourceItems)
80 if len(sourceItems) != 3 {
81 return nil, fmt.Errorf("Got invalid source: %s", item)
82 }
83 path := sourceItems[1] + "/" + sourceItems[2]
84 if _, ok := temps[path]; !ok {
85 temps[path] = make([]string, 1)
86 }
87 temps[path] = append(temps[path], tmp[2])
88 }
89 return temps, nil
90}