Skip to content

Commit 56a5a40

Browse files
Vadim Rutkovskyvrutkovs
authored andcommitted
certrotation: set RefreshPeriod automatically
1 parent 039cbeb commit 56a5a40

File tree

3 files changed

+47
-4
lines changed

3 files changed

+47
-4
lines changed

pkg/operator/certrotation/signer.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ func (c RotatedSigningCASecret) EnsureSigningCertKeyPair(ctx context.Context) (*
9292
reason = "secret doesn't exist"
9393
}
9494
c.EventRecorder.Eventf("SignerUpdateRequired", "%q in %q requires a new signing cert/key pair: %v", c.Name, c.Namespace, reason)
95-
if err := setSigningCertKeyPairSecret(signingCertKeyPairSecret, c.Validity, c.AdditionalAnnotations); err != nil {
95+
if err := setSigningCertKeyPairSecret(signingCertKeyPairSecret, c.Validity, c.Refresh, c.AdditionalAnnotations); err != nil {
9696
return nil, false, err
9797
}
9898

@@ -200,7 +200,7 @@ func getValidityFromAnnotations(annotations map[string]string) (notBefore time.T
200200
}
201201

202202
// setSigningCertKeyPairSecret creates a new signing cert/key pair and sets them in the secret
203-
func setSigningCertKeyPairSecret(signingCertKeyPairSecret *corev1.Secret, validity time.Duration, annotations AdditionalAnnotations) error {
203+
func setSigningCertKeyPairSecret(signingCertKeyPairSecret *corev1.Secret, validity, refresh time.Duration, annotations AdditionalAnnotations) error {
204204
signerName := fmt.Sprintf("%s_%s@%d", signingCertKeyPairSecret.Namespace, signingCertKeyPairSecret.Name, time.Now().Unix())
205205
ca, err := crypto.MakeSelfSignedCAConfigForDuration(signerName, validity)
206206
if err != nil {
@@ -223,6 +223,7 @@ func setSigningCertKeyPairSecret(signingCertKeyPairSecret *corev1.Secret, validi
223223
signingCertKeyPairSecret.Data["tls.key"] = keyBytes.Bytes()
224224
annotations.NotBefore = ca.Certs[0].NotBefore.Format(time.RFC3339)
225225
annotations.NotAfter = ca.Certs[0].NotAfter.Format(time.RFC3339)
226+
annotations.RefreshPeriod = durationRound(refresh)
226227
signingCertKeyPairSecret.Annotations[CertificateIssuer] = ca.Certs[0].Issuer.CommonName
227228

228229
_ = annotations.EnsureTLSMetadataUpdate(&signingCertKeyPairSecret.ObjectMeta)

pkg/operator/certrotation/target.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ func (c RotatedSelfSignedCertKeySecret) EnsureTargetCertKeyPair(ctx context.Cont
121121

122122
if reason := c.CertCreator.NeedNewTargetCertKeyPair(targetCertKeyPairSecret, signingCertKeyPair, caBundleCerts, c.Refresh, c.RefreshOnlyWhenExpired, creationRequired); len(reason) > 0 {
123123
c.EventRecorder.Eventf("TargetUpdateRequired", "%q in %q requires a new target cert/key pair: %v", c.Name, c.Namespace, reason)
124-
if err := setTargetCertKeyPairSecret(targetCertKeyPairSecret, c.Validity, signingCertKeyPair, c.CertCreator, c.AdditionalAnnotations); err != nil {
124+
if err := setTargetCertKeyPairSecret(targetCertKeyPairSecret, c.Validity, c.Refresh, signingCertKeyPair, c.CertCreator, c.AdditionalAnnotations); err != nil {
125125
return nil, err
126126
}
127127

@@ -234,7 +234,7 @@ func needNewTargetCertKeyPairForTime(annotations map[string]string, signer *cryp
234234

235235
// setTargetCertKeyPairSecret creates a new cert/key pair and sets them in the secret. Only one of client, serving, or signer rotation may be specified.
236236
// TODO refactor with an interface for actually signing and move the one-of check higher in the stack.
237-
func setTargetCertKeyPairSecret(targetCertKeyPairSecret *corev1.Secret, validity time.Duration, signer *crypto.CA, certCreator TargetCertCreator, annotations AdditionalAnnotations) error {
237+
func setTargetCertKeyPairSecret(targetCertKeyPairSecret *corev1.Secret, validity, refresh time.Duration, signer *crypto.CA, certCreator TargetCertCreator, annotations AdditionalAnnotations) error {
238238
if targetCertKeyPairSecret.Annotations == nil {
239239
targetCertKeyPairSecret.Annotations = map[string]string{}
240240
}
@@ -258,8 +258,10 @@ func setTargetCertKeyPairSecret(targetCertKeyPairSecret *corev1.Secret, validity
258258
if err != nil {
259259
return err
260260
}
261+
261262
annotations.NotBefore = certKeyPair.Certs[0].NotBefore.Format(time.RFC3339)
262263
annotations.NotAfter = certKeyPair.Certs[0].NotAfter.Format(time.RFC3339)
264+
annotations.RefreshPeriod = durationRound(refresh)
263265
targetCertKeyPairSecret.Annotations[CertificateIssuer] = certKeyPair.Certs[0].Issuer.CommonName
264266

265267
_ = annotations.EnsureTLSMetadataUpdate(&targetCertKeyPairSecret.ObjectMeta)

pkg/operator/certrotation/utils.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package certrotation
2+
3+
import (
4+
"strconv"
5+
"time"
6+
)
7+
8+
// durationRound formats a duration into a human-readable string.
9+
// Unlike Go's built-in `time.Duration.String()`, which returns a string like "72h3m0s", this function returns a more concise format like "3d" or "2h30m".
10+
// Implementation is taken from https://github.com/gomodules/sprig/blob/master/date.go#L97-L139
11+
func durationRound(d time.Duration) string {
12+
u := uint64(d)
13+
if d < 0 {
14+
u = -u
15+
}
16+
17+
var (
18+
year = uint64(time.Hour) * 24 * 365
19+
month = uint64(time.Hour) * 24 * 30
20+
day = uint64(time.Hour) * 24
21+
hour = uint64(time.Hour)
22+
minute = uint64(time.Minute)
23+
second = uint64(time.Second)
24+
)
25+
switch {
26+
case u > year:
27+
return strconv.FormatUint(u/year, 10) + "y"
28+
case u > month:
29+
return strconv.FormatUint(u/month, 10) + "mo"
30+
case u > day:
31+
return strconv.FormatUint(u/day, 10) + "d"
32+
case u > hour:
33+
return strconv.FormatUint(u/hour, 10) + "h"
34+
case u > minute:
35+
return strconv.FormatUint(u/minute, 10) + "m"
36+
case u > second:
37+
return strconv.FormatUint(u/second, 10) + "s"
38+
}
39+
return "0s"
40+
}

0 commit comments

Comments
 (0)