-
Notifications
You must be signed in to change notification settings - Fork 444
/
run.go
115 lines (98 loc) · 3.45 KB
/
run.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
package run
import (
"context"
"github.com/rotisserie/eris"
"github.com/solo-io/gloo/jobs/pkg/certgen"
"github.com/solo-io/gloo/jobs/pkg/kube"
"github.com/solo-io/gloo/projects/gloo/cli/pkg/helpers"
"github.com/solo-io/go-utils/contextutils"
"go.uber.org/zap"
v1 "k8s.io/api/core/v1"
)
type Options struct {
SvcName string
SvcNamespace string
SecretName string
SecretNamespace string
ServerCertSecretFileName string
ServerCertAuthorityFileName string
ServerKeySecretFileName string
ValidatingWebhookConfigurationName string
ForceRotation bool
}
func Run(ctx context.Context, opts Options) error {
if opts.SvcNamespace == "" {
return eris.Errorf("must provide svc-namespace")
}
if opts.SvcName == "" {
return eris.Errorf("must provide svc-name")
}
if opts.SecretNamespace == "" {
return eris.Errorf("must provide secret-namespace")
}
if opts.SecretName == "" {
return eris.Errorf("must provide secret-name")
}
if opts.ServerCertSecretFileName == "" {
return eris.Errorf("must provide name for the server cert entry in the secret data")
}
if opts.ServerCertAuthorityFileName == "" {
return eris.Errorf("must provide name for the cert authority entry in the secret data")
}
if opts.ServerKeySecretFileName == "" {
return eris.Errorf("must provide name for the server key entry in the secret data")
}
kubeClient := helpers.MustKubeClient()
var secret *v1.Secret
var err error
if !opts.ForceRotation {
// check if there is an existing valid TLS secret
secret, err = kube.GetExistingValidTlsSecret(ctx, kubeClient, opts.SecretName, opts.SecretNamespace,
opts.SvcName, opts.SvcNamespace)
if err != nil {
return eris.Wrapf(err, "failed validating existing secret")
}
if secret != nil {
contextutils.LoggerFrom(ctx).Infow("existing TLS secret found, skipping update to TLS secret since the old TLS secret is still valid",
zap.String("secretName", opts.SecretName),
zap.String("secretNamespace", opts.SecretNamespace))
}
}
// if ForceRotation=true or there is no existing valid secret, generate one
if secret == nil {
certs, err := certgen.GenCerts(opts.SvcName, opts.SvcNamespace)
if err != nil {
return eris.Wrapf(err, "generating self-signed certs and key")
}
caCert := append(certs.ServerCertificate, certs.CaCertificate...)
secretConfig := kube.TlsSecret{
SecretName: opts.SecretName,
SecretNamespace: opts.SecretNamespace,
PrivateKeyFileName: opts.ServerKeySecretFileName,
CertFileName: opts.ServerCertSecretFileName,
CaBundleFileName: opts.ServerCertAuthorityFileName,
PrivateKey: certs.ServerCertKey,
Cert: caCert,
CaBundle: certs.CaCertificate,
}
secret, err = kube.CreateTlsSecret(ctx, kubeClient, secretConfig)
if err != nil {
return eris.Wrapf(err, "failed creating secret")
}
}
vwcName := opts.ValidatingWebhookConfigurationName
if vwcName == "" {
contextutils.LoggerFrom(ctx).Infof("no ValidatingWebhookConfiguration provided. finished successfully.")
return nil
}
vwcConfig := kube.WebhookTlsConfig{
ServiceName: opts.SvcName,
ServiceNamespace: opts.SvcNamespace,
CaBundle: secret.Data[opts.ServerCertAuthorityFileName],
}
if err := kube.UpdateValidatingWebhookConfigurationCaBundle(ctx, kubeClient, vwcName, vwcConfig); err != nil {
return eris.Wrapf(err, "failed patching validating webhook config")
}
contextutils.LoggerFrom(ctx).Infof("finished successfully.")
return nil
}