-
Notifications
You must be signed in to change notification settings - Fork 24
/
helm.go
122 lines (100 loc) · 3.27 KB
/
helm.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
package clients
import (
"fmt"
"sync"
"github.com/hashicorp/go-hclog"
"golang.org/x/xerrors"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/chart/loader"
"helm.sh/helm/v3/pkg/cli"
"helm.sh/helm/v3/pkg/cli/values"
"helm.sh/helm/v3/pkg/getter"
"helm.sh/helm/v3/pkg/kube"
)
var helmLock sync.Mutex
func init() {
// create a global lock as it seems map write in Helm is not thread safe
helmLock = sync.Mutex{}
}
// Helm defines an interface for a client which can manage Helm charts
type Helm interface {
Create(kubeConfig, name, namespace string, createNamespace bool, chartPath, valuesPath string, valuesString map[string]string) error
Destroy(kubeConfig, name, namespace string) error
}
type HelmImpl struct {
log hclog.Logger
}
func NewHelm(l hclog.Logger) Helm {
return &HelmImpl{l}
}
// Create a new install of the chart
func (h *HelmImpl) Create(kubeConfig, name, namespace string, createNamespace bool, chartPath, valuesPath string, valuesString map[string]string) error {
// set the kubeclient for Helm
s := kube.GetConfig(kubeConfig, "default", namespace)
cfg := &action.Configuration{}
err := cfg.Init(s, namespace, "", func(format string, v ...interface{}) {
h.log.Debug("Helm debug message", "message", fmt.Sprintf(format, v...))
})
if err != nil {
return xerrors.Errorf("unalbe to iniailize Helm: %w", err)
}
client := action.NewInstall(cfg)
client.ReleaseName = name
client.Namespace = namespace
client.CreateNamespace = createNamespace
settings := cli.EnvSettings{}
p := getter.All(&settings)
vo := values.Options{}
vo.StringValues = []string{}
// add the string values to the collection
for k, v := range valuesString {
vo.StringValues = append(vo.StringValues, fmt.Sprintf("%s=%s", k, v))
}
// if we have an overriden values file set it
if valuesPath != "" {
vo.ValueFiles = []string{valuesPath}
}
h.log.Debug("Creating chart from config", "ref", name, "path", chartPath)
cp, err := client.ChartPathOptions.LocateChart(chartPath, &settings)
if err != nil {
return xerrors.Errorf("Error locating chart: %w", err)
}
h.log.Debug("Loading chart", "ref", name, "path", cp)
chartRequested, err := loader.Load(cp)
if err != nil {
return xerrors.Errorf("Error loading chart: %w", err)
}
vals, err := vo.MergeValues(p)
if err != nil {
return xerrors.Errorf("Error merging Helm values: %w", err)
}
h.log.Debug("Validate chart", "ref", name)
err = chartRequested.Validate()
if err != nil {
return xerrors.Errorf("Error validating chart: %w", err)
}
h.log.Debug("Run chart", "ref", name)
_, err = client.Run(chartRequested, vals)
if err != nil {
return xerrors.Errorf("Error running chart: %w", err)
}
return nil
}
// Destroy removes an installed Helm chart from the system
func (h *HelmImpl) Destroy(kubeConfig, name, namespace string) error {
s := kube.GetConfig(kubeConfig, "default", namespace)
cfg := &action.Configuration{}
err := cfg.Init(s, namespace, "", func(format string, v ...interface{}) {
h.log.Debug("Helm debug message", "message", fmt.Sprintf(format, v...))
})
//settings := cli.EnvSettings{}
//p := getter.All(&settings)
//vo := values.Options{}
client := action.NewUninstall(cfg)
_, err = client.Run(name)
if err != nil {
h.log.Debug("Unable to remove chart, exit silently", "err", err)
return err
}
return nil
}