blob: cd399857bad75d95c5ae9a1346480e5db3f38a84 [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,
giolekvad5a58c42020-05-07 22:18:35 +040015 values map[string]string) (map[string][]string, error)
16}
17
18type helmUnpacker struct {
19 helmBin string
20}
21
22func NewHelmUnpacker(helmBin string) Unpacker {
23 return &helmUnpacker{helmBin}
24}
25
26func (h *helmUnpacker) Unpack(
27 archive string,
28 namespace string,
giolekvad5a58c42020-05-07 22:18:35 +040029 values map[string]string) (map[string][]string, error) {
giolekva6c588c82020-05-09 12:42:06 +040030 cmd := h.generateHelmInstallCmd(archive, namespace, values)
giolekvad5a58c42020-05-07 22:18:35 +040031 glog.Info(cmd.String())
32 var stdout strings.Builder
33 var stderr strings.Builder
34 cmd.Stdout = &stdout
35 cmd.Stderr = &stderr
36 err := cmd.Run()
37 if err != nil {
38 return nil, errors.New(stderr.String())
39 }
40 return extractTemplates(stdout.String())
41}
42
43func (h *helmUnpacker) generateHelmInstallCmd(
44 archive string,
45 namespace string,
giolekvad5a58c42020-05-07 22:18:35 +040046 values map[string]string) *exec.Cmd {
47 cmd := exec.Command(h.helmBin)
48 cmd.Args = append(cmd.Args, "template")
49 cmd.Args = append(cmd.Args, fmt.Sprintf("--namespace=%s", namespace))
giolekvad6bec022020-05-09 12:41:18 +040050 cmd.Args = append(cmd.Args, "--generate-name")
giolekvad5a58c42020-05-07 22:18:35 +040051 cmd.Args = append(cmd.Args, fmt.Sprintf("%s", archive))
52 // TODO(giolekva): validate values
53 for key, value := range values {
54 cmd.Args = append(cmd.Args, fmt.Sprintf("--set=%s=%s", key, value))
55 }
56 return cmd
57}
58
59func extractTemplates(bundle string) (map[string][]string, error) {
60 items := strings.Split(bundle, "---")
61 temps := make(map[string][]string)
62 for _, item := range items {
63 if len(item) == 0 {
64 continue
65 }
66 tmp := strings.SplitN(item, "\n", 3)
67 if len(tmp) != 3 {
68 return nil, fmt.Errorf("Got invalid template: %s", item)
69 }
70 source := tmp[1]
71 glog.Info(source)
72 // if !strings.HasPrefix(source, "\n# Source: ") {
73 // return nil, fmt.Errorf("Got invalid source: %s", item)
74 // }
75 sourceItems := strings.Split(source, "/")
76 glog.Info(sourceItems)
77 if len(sourceItems) != 3 {
78 return nil, fmt.Errorf("Got invalid source: %s", item)
79 }
80 path := sourceItems[1] + "/" + sourceItems[2]
81 if _, ok := temps[path]; !ok {
82 temps[path] = make([]string, 1)
83 }
84 temps[path] = append(temps[path], tmp[2])
85 }
86 return temps, nil
87}