forked from fluxcd/flux
-
Notifications
You must be signed in to change notification settings - Fork 0
/
helm.go
117 lines (103 loc) · 3.1 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
package helm
import (
"fmt"
"time"
"github.com/go-kit/kit/log"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
k8shelm "k8s.io/helm/pkg/helm"
rls "k8s.io/helm/pkg/proto/hapi/services"
"k8s.io/helm/pkg/tlsutil"
)
const (
GitOperationTimeout = 30 * time.Second
)
type TillerOptions struct {
Host string
Port string
Namespace string
TLSVerify bool
TLSEnable bool
TLSKey string
TLSCert string
TLSCACert string
TLSHostname string
}
// Helm struct provides access to helm client
type Helm struct {
logger log.Logger
Host string
*k8shelm.Client
}
// newClient creates a new helm client
func newClient(kubeClient *kubernetes.Clientset, opts TillerOptions) (*k8shelm.Client, string, error) {
host, err := tillerHost(kubeClient, opts)
if err != nil {
return &k8shelm.Client{}, "", err
}
//host = "tiller-deploy.kube-system:44134"
options := []k8shelm.Option{k8shelm.Host(host)}
if opts.TLSVerify || opts.TLSEnable {
tlsopts := tlsutil.Options{
KeyFile: opts.TLSKey,
CertFile: opts.TLSCert,
InsecureSkipVerify: true,
}
if opts.TLSVerify {
tlsopts.CaCertFile = opts.TLSCACert
tlsopts.InsecureSkipVerify = false
}
if opts.TLSHostname != "" {
tlsopts.ServerName = opts.TLSHostname
}
tlscfg, err := tlsutil.ClientConfig(tlsopts)
if err != nil {
return nil, "", err
}
options = append(options, k8shelm.WithTLS(tlscfg))
}
return k8shelm.NewClient(options...), host, nil
}
func ClientSetup(logger log.Logger, kubeClient *kubernetes.Clientset, tillerOpts TillerOptions) *k8shelm.Client {
var helmClient *k8shelm.Client
var host string
var err error
for {
helmClient, host, err = newClient(kubeClient, tillerOpts)
if err != nil {
logger.Log("error", fmt.Sprintf("Error creating helm client: %s", err.Error()))
time.Sleep(20 * time.Second)
continue
}
version, err := GetTillerVersion(helmClient, host)
if err != nil {
logger.Log("warning", "unable to connect to Tiller", "err", err, "host", host, "options", fmt.Sprintf("%+v", tillerOpts))
time.Sleep(20 * time.Second)
continue
}
logger.Log("info", "connected to Tiller", "version", version, "host", host, "options", fmt.Sprintf("%+v", tillerOpts))
break
}
return helmClient
}
// GetTillerVersion retrieves tiller version
func GetTillerVersion(cl *k8shelm.Client, h string) (string, error) {
var v *rls.GetVersionResponse
var err error
voption := k8shelm.VersionOption(k8shelm.Host(h))
if v, err = cl.GetVersion(voption); err != nil {
return "", fmt.Errorf("error getting tiller version: %v", err)
}
return v.GetVersion().String(), nil
}
// TODO ... set up based on the tiller existing in the cluster, if no ops given
func tillerHost(kubeClient *kubernetes.Clientset, opts TillerOptions) (string, error) {
if opts.Host == "" || opts.Port == "" {
ts, err := kubeClient.CoreV1().Services(opts.Namespace).Get("tiller-deploy", metav1.GetOptions{})
if err != nil {
return "", err
}
return fmt.Sprintf("%s.%s:%v", ts.Name, ts.Namespace, ts.Spec.Ports[0].Port), nil
}
return fmt.Sprintf("%s:%s", opts.Host, opts.Port), nil
}