Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 33 additions & 3 deletions pkg/assets/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,18 @@ import (
"encoding/base64"
"strings"
"text/template"
"time"

"k8s.io/client-go/util/cert"
)

var templateFuncs = map[string]interface{}{
"base64": base64encode,
"indent": indent,
"load": load,
"notAfter": notAfter,
"notBefore": notBefore,
"issuer": issuer,
"base64": base64encode,
"indent": indent,
"load": load,
}

func indent(indention int, v []byte) string {
Expand All @@ -22,6 +28,30 @@ func base64encode(v []byte) string {
return base64.StdEncoding.EncodeToString(v)
}

func notAfter(certBytes []byte) string {
certs, err := cert.ParseCertsPEM(certBytes)
if err != nil {
panic(err)
}
return certs[0].NotAfter.Format(time.RFC3339)
}

func notBefore(certBytes []byte) string {
certs, err := cert.ParseCertsPEM(certBytes)
if err != nil {
panic(err)
}
return certs[0].NotBefore.Format(time.RFC3339)
}

func issuer(certBytes []byte) string {
certs, err := cert.ParseCertsPEM(certBytes)
if err != nil {
panic(err)
}
return certs[0].Issuer.CommonName
}

func load(n string, assets map[string][]byte) []byte {
return assets[n]
}
Expand Down
10 changes: 6 additions & 4 deletions pkg/operator/certrotation/client_cert_rotation_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ import (
)

const (
// CertificateExpiryAnnotation contains the certificate expiration date in RFC3339 format.
CertificateExpiryAnnotation = "auth.openshift.io/certificate-expiry-date"
// CertificateSignedBy contains the common name of the certificate that signed another certificate.
CertificateSignedBy = "auth.openshift.io/certificate-signed-by"
// CertificateNotBeforeAnnotation contains the certificate expiration date in RFC3339 format.
CertificateNotBeforeAnnotation = "auth.openshift.io/certificate-not-before"
// CertificateNotAfterAnnotation contains the certificate expiration date in RFC3339 format.
CertificateNotAfterAnnotation = "auth.openshift.io/certificate-not-after"
// CertificateIssuer contains the common name of the certificate that signed another certificate.
CertificateIssuer = "auth.openshift.io/certificate-issuer"
)

const workQueueKey = "key"
Expand Down
6 changes: 4 additions & 2 deletions pkg/operator/certrotation/signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func (c SigningRotation) ensureSigningCertKeyPair() (*crypto.CA, error) {
}

func needNewSigningCertKeyPair(annotations map[string]string, validity time.Duration, renewalPercentage float32) string {
signingCertKeyPairExpiry := annotations[CertificateExpiryAnnotation]
signingCertKeyPairExpiry := annotations[CertificateNotAfterAnnotation]
if len(signingCertKeyPairExpiry) == 0 {
return "missing target expiry"
}
Expand Down Expand Up @@ -104,7 +104,9 @@ func setSigningCertKeyPairSecret(signingCertKeyPairSecret *corev1.Secret, validi
}
signingCertKeyPairSecret.Data["tls.crt"] = certBytes.Bytes()
signingCertKeyPairSecret.Data["tls.key"] = keyBytes.Bytes()
signingCertKeyPairSecret.Annotations[CertificateExpiryAnnotation] = ca.Certs[0].NotAfter.Format(time.RFC3339)
signingCertKeyPairSecret.Annotations[CertificateNotAfterAnnotation] = ca.Certs[0].NotAfter.Format(time.RFC3339)
signingCertKeyPairSecret.Annotations[CertificateNotBeforeAnnotation] = ca.Certs[0].NotBefore.Format(time.RFC3339)
signingCertKeyPairSecret.Annotations[CertificateIssuer] = ca.Certs[0].Issuer.CommonName

return nil
}
2 changes: 1 addition & 1 deletion pkg/operator/certrotation/signer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func TestEnsureSigningCertKeyPair(t *testing.T) {
initialSecret: &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{Namespace: "ns", Name: "signer",
Annotations: map[string]string{
"auth.openshift.io/certificate-expiry-date": "2108-09-08T22:47:31-07:00",
"auth.openshift.io/certificate-not-after": "2108-09-08T22:47:31-07:00",
}},
},
verifyActions: func(t *testing.T, client *kubefake.Clientset) {
Expand Down
9 changes: 5 additions & 4 deletions pkg/operator/certrotation/target.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func needNewTargetCertKeyPair(annotations map[string]string, signer *crypto.CA,
}

// check the signer common name against all the common names in our ca bundle so we don't refresh early
signerCommonName := annotations[CertificateSignedBy]
signerCommonName := annotations[CertificateIssuer]
if len(signerCommonName) == 0 {
return "missing issuer name"
}
Expand Down Expand Up @@ -123,7 +123,7 @@ func needNewTargetCertKeyPair(annotations map[string]string, signer *crypto.CA,
//
//So with a cert percentage of 75% and equally long CA and cert validities at the worst case we start at 85% of the cert to renew, trying again every minute.
func needNewTargetCertKeyPairForTime(annotations map[string]string, signer *crypto.CA, validity time.Duration, renewalPercentage float32) string {
targetExpiry := annotations[CertificateExpiryAnnotation]
targetExpiry := annotations[CertificateNotAfterAnnotation]
if len(targetExpiry) == 0 {
return "missing target expiry"
}
Expand Down Expand Up @@ -202,8 +202,9 @@ func setTargetCertKeyPairSecret(targetCertKeyPairSecret *corev1.Secret, validity
if err != nil {
return err
}
targetCertKeyPairSecret.Annotations[CertificateExpiryAnnotation] = certKeyPair.Certs[0].NotAfter.Format(time.RFC3339)
targetCertKeyPairSecret.Annotations[CertificateSignedBy] = signer.Config.Certs[0].Subject.CommonName
targetCertKeyPairSecret.Annotations[CertificateNotAfterAnnotation] = certKeyPair.Certs[0].NotAfter.Format(time.RFC3339)
targetCertKeyPairSecret.Annotations[CertificateNotBeforeAnnotation] = certKeyPair.Certs[0].NotBefore.Format(time.RFC3339)
targetCertKeyPairSecret.Annotations[CertificateIssuer] = certKeyPair.Certs[0].Issuer.CommonName

return nil
}
6 changes: 3 additions & 3 deletions pkg/operator/certrotation/target_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func TestNeedNewTargetCertKeyPairForTime(t *testing.T) {
},
{
name: "malformed",
annotations: map[string]string{CertificateExpiryAnnotation: "malformed"},
annotations: map[string]string{CertificateNotAfterAnnotation: "malformed"},
signerFn: func() (*crypto.CA, error) {
return nowCert, nil
},
Expand All @@ -64,7 +64,7 @@ func TestNeedNewTargetCertKeyPairForTime(t *testing.T) {
},
{
name: "past midpoint and cert is ready",
annotations: map[string]string{CertificateExpiryAnnotation: now.Add(45 * time.Minute).Format(time.RFC3339)},
annotations: map[string]string{CertificateNotAfterAnnotation: now.Add(45 * time.Minute).Format(time.RFC3339)},
signerFn: func() (*crypto.CA, error) {
return elevenMinutesBeforeNowCert, nil
},
Expand All @@ -74,7 +74,7 @@ func TestNeedNewTargetCertKeyPairForTime(t *testing.T) {
},
{
name: "past midpoint and cert is new",
annotations: map[string]string{CertificateExpiryAnnotation: now.Add(45 * time.Minute).Format(time.RFC3339)},
annotations: map[string]string{CertificateNotAfterAnnotation: now.Add(45 * time.Minute).Format(time.RFC3339)},
signerFn: func() (*crypto.CA, error) {
return nowCert, nil
},
Expand Down