-
Notifications
You must be signed in to change notification settings - Fork 81
/
kubeconfig.go
126 lines (115 loc) · 3.61 KB
/
kubeconfig.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
123
124
125
126
package eks
import (
"bytes"
"context"
"errors"
"fmt"
"io/ioutil"
"strings"
"text/template"
"time"
"go.uber.org/zap"
"k8s.io/utils/exec"
)
type kubeconfig struct {
ClusterAPIServerEndpoint string
ClusterCA string
AWSIAMAuthenticatorPath string
ClusterName string
}
const tmplKUBECONFIG = `
apiVersion: v1
kind: Config
clusters:
- cluster:
server: {{ .ClusterAPIServerEndpoint }}
certificate-authority-data: {{ .ClusterCA }}
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: aws
name: aws
current-context: aws
preferences: {}
users:
- name: aws
user:
exec:
apiVersion: client.authentication.k8s.io/v1alpha1
command: {{ .AWSIAMAuthenticatorPath }}
args:
- token
- -i
- {{ .ClusterName }}
`
// https://docs.aws.amazon.com/cli/latest/reference/eks/update-kubeconfig.html
// https://docs.aws.amazon.com/eks/latest/userguide/create-kubeconfig.html
// aws eks update-kubeconfig --name --role-arn --kubeconfig
func (ts *Tester) updateKUBECONFIG() (err error) {
if ts.cfg.AWSIAMAuthenticatorPath != "" && ts.cfg.AWSIAMAuthenticatorDownloadURL != "" {
tpl := template.Must(template.New("tmplKUBECONFIG").Parse(tmplKUBECONFIG))
buf := bytes.NewBuffer(nil)
if err = tpl.Execute(buf, kubeconfig{
ClusterAPIServerEndpoint: ts.cfg.Status.ClusterAPIServerEndpoint,
ClusterCA: ts.cfg.Status.ClusterCA,
AWSIAMAuthenticatorPath: ts.cfg.AWSIAMAuthenticatorPath,
ClusterName: ts.cfg.Name,
}); err != nil {
return err
}
ts.lg.Info("writing KUBECONFIG with aws-iam-authenticator", zap.String("kubeconfig-path", ts.cfg.KubeConfigPath))
if err = ioutil.WriteFile(ts.cfg.KubeConfigPath, buf.Bytes(), 0777); err != nil {
return err
}
ts.lg.Info("wrote KUBECONFIG with aws-iam-authenticator", zap.String("kubeconfig-path", ts.cfg.KubeConfigPath))
return ts.cfg.Sync()
}
args := []string{
ts.cfg.AWSCLIPath,
"eks",
fmt.Sprintf("--region=%s", ts.cfg.Region),
"update-kubeconfig",
fmt.Sprintf("--name=%s", ts.cfg.Name),
fmt.Sprintf("--kubeconfig=%s", ts.cfg.KubeConfigPath),
"--verbose",
}
if ts.cfg.Parameters.ResolverURL != "" {
args = append(args, fmt.Sprintf("--endpoint=%s", ts.cfg.Parameters.ResolverURL))
}
cmd := strings.Join(args, " ")
ts.lg.Info("writing KUBECONFIG with 'aws eks update-kubeconfig'",
zap.String("kubeconfig-path", ts.cfg.KubeConfigPath),
zap.String("cmd", cmd),
)
retryStart, waitDur := time.Now(), 3*time.Minute
var output []byte
for time.Now().Sub(retryStart) < waitDur {
select {
case <-ts.stopCreationCh:
return errors.New("update-kubeconfig aborted")
case <-ts.interruptSig:
return errors.New("update-kubeconfig aborted")
case <-time.After(5 * time.Second):
}
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
output, err = exec.New().CommandContext(ctx, args[0], args[1:]...).CombinedOutput()
cancel()
if err != nil {
ts.lg.Warn("'aws eks update-kubeconfig' failed", zap.Error(err))
if !strings.Contains(string(output), "Cluster status not active") || !strings.Contains(err.Error(), "exit") {
return fmt.Errorf("'aws eks update-kubeconfig' failed (output %q, error %v)", string(output), err)
}
continue
}
ts.lg.Info("'aws eks update-kubeconfig' success", zap.String("kubeconfig-path", ts.cfg.KubeConfigPath))
break
}
if err != nil {
ts.lg.Warn("failed 'aws eks update-kubeconfig'", zap.String("output", string(output)), zap.Error(err))
return err
}
ts.lg.Info("ran 'aws eks update-kubeconfig'")
fmt.Printf("\n\n'%s' output:\n\n%s\n\n", cmd, strings.TrimSpace(string(output)))
return nil
}