23
23
package reconcile
24
24
25
25
import (
26
- "crypto/x509"
27
- "encoding/pem"
28
- "time"
29
-
30
26
"github.com/rs/zerolog"
31
27
"github.com/rs/zerolog/log"
32
28
"k8s.io/api/core/v1"
@@ -58,7 +54,7 @@ func (d *Reconciler) CreatePlan() error {
58
54
apiObject := d .context .GetAPIObject ()
59
55
spec := d .context .GetSpec ()
60
56
status , lastVersion := d .context .GetStatus ()
61
- newPlan , changed := createPlan (d .log , apiObject , status .Plan , spec , status , pods , d .context .GetTLSKeyfile )
57
+ newPlan , changed := createPlan (d .log , apiObject , status .Plan , spec , status , pods , d .context .GetTLSKeyfile , d . context . GetTLSCA )
62
58
63
59
// If not change, we're done
64
60
if ! changed {
@@ -83,7 +79,8 @@ func (d *Reconciler) CreatePlan() error {
83
79
func createPlan (log zerolog.Logger , apiObject metav1.Object ,
84
80
currentPlan api.Plan , spec api.DeploymentSpec ,
85
81
status api.DeploymentStatus , pods []v1.Pod ,
86
- getTLSKeyfile func (group api.ServerGroup , member api.MemberStatus ) (string , error )) (api.Plan , bool ) {
82
+ getTLSKeyfile func (group api.ServerGroup , member api.MemberStatus ) (string , error ),
83
+ getTLSCA func (string ) (string , string , bool , error )) (api.Plan , bool ) {
87
84
if len (currentPlan ) > 0 {
88
85
// Plan already exists, complete that first
89
86
return currentPlan , false
@@ -178,41 +175,14 @@ func createPlan(log zerolog.Logger, apiObject metav1.Object,
178
175
})
179
176
}
180
177
178
+ // Check for the need to rotate TLS CA certificate and all members
179
+ if len (plan ) == 0 {
180
+ plan = createRotateTLSCAPlan (log , spec , status , getTLSCA )
181
+ }
182
+
181
183
// Check for the need to rotate TLS certificate of a members
182
- if len (plan ) == 0 && spec .TLS .IsSecure () {
183
- status .Members .ForeachServerGroup (func (group api.ServerGroup , members api.MemberStatusList ) error {
184
- for _ , m := range members {
185
- if len (plan ) > 0 {
186
- // Only 1 change at a time
187
- continue
188
- }
189
- if m .Phase != api .MemberPhaseCreated {
190
- // Only make changes when phase is created
191
- continue
192
- }
193
- if group == api .ServerGroupSyncWorkers {
194
- // SyncWorkers have no externally created TLS keyfile
195
- continue
196
- }
197
- // Load keyfile
198
- keyfile , err := getTLSKeyfile (group , m )
199
- if err != nil {
200
- log .Warn ().Err (err ).
201
- Str ("role" , group .AsRole ()).
202
- Str ("id" , m .ID ).
203
- Msg ("Failed to get TLS secret" )
204
- continue
205
- }
206
- renewalNeeded := tlsKeyfileNeedsRenewal (log , keyfile )
207
- if renewalNeeded {
208
- plan = append (append (plan ,
209
- api .NewAction (api .ActionTypeRenewTLSCertificate , group , m .ID )),
210
- createRotateMemberPlan (log , m , group , "TLS certificate renewal" )... ,
211
- )
212
- }
213
- }
214
- return nil
215
- })
184
+ if len (plan ) == 0 {
185
+ plan = createRotateTLSServerCertificatePlan (log , spec , status , getTLSKeyfile )
216
186
}
217
187
218
188
// Return plan
@@ -304,44 +274,6 @@ func normalizeServiceAccountName(name string) string {
304
274
return ""
305
275
}
306
276
307
- // tlsKeyfileNeedsRenewal decides if the certificate in the given keyfile
308
- // should be renewed.
309
- func tlsKeyfileNeedsRenewal (log zerolog.Logger , keyfile string ) bool {
310
- raw := []byte (keyfile )
311
- for {
312
- var derBlock * pem.Block
313
- derBlock , raw = pem .Decode (raw )
314
- if derBlock == nil {
315
- break
316
- }
317
- if derBlock .Type == "CERTIFICATE" {
318
- cert , err := x509 .ParseCertificate (derBlock .Bytes )
319
- if err != nil {
320
- // We do not understand the certificate, let's renew it
321
- log .Warn ().Err (err ).Msg ("Failed to parse x509 certificate. Renewing it" )
322
- return true
323
- }
324
- if cert .IsCA {
325
- // Only look at the server certificate, not CA or intermediate
326
- continue
327
- }
328
- // Check expiration date. Renewal at 2/3 of lifetime.
329
- ttl := cert .NotAfter .Sub (cert .NotBefore )
330
- expirationDate := cert .NotBefore .Add ((ttl / 3 ) * 2 )
331
- if expirationDate .Before (time .Now ()) {
332
- // We should renew now
333
- log .Debug ().
334
- Str ("not-before" , cert .NotBefore .String ()).
335
- Str ("not-after" , cert .NotAfter .String ()).
336
- Str ("expiration-date" , expirationDate .String ()).
337
- Msg ("TLS certificate renewal needed" )
338
- return true
339
- }
340
- }
341
- }
342
- return false
343
- }
344
-
345
277
// createScalePlan creates a scaling plan for a single server group
346
278
func createScalePlan (log zerolog.Logger , members api.MemberStatusList , group api.ServerGroup , count int ) api.Plan {
347
279
var plan api.Plan
0 commit comments