Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
Revert "Disable automatic CA rotation for now"
This reverts commit 6f0fb7b.
  • Loading branch information
marun committed Jan 28, 2020
commit e3cdca74bd55f20a2222d5f6dfe661e765ef2bc9
44 changes: 0 additions & 44 deletions pkg/operator/config.go

This file was deleted.

45 changes: 36 additions & 9 deletions pkg/operator/rotate.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package operator
import (
"crypto/rsa"
"crypto/x509"
"encoding/json"
"fmt"
"time"

Expand All @@ -26,6 +27,13 @@ const (
minimumTrustDuration = 182 * 24 * time.Hour
)

type unsupportedServiceCAConfig struct {
ForceRotation forceRotationConfig `json:"forceRotation"`
}
type forceRotationConfig struct {
Reason string `json:"reason"`
}

type signingCA struct {
config *crypto.TLSCertificateConfig
bundle []*x509.Certificate
Expand Down Expand Up @@ -64,19 +72,14 @@ func (ca *signingCA) updateSigningSecret(secret *corev1.Secret) error {
// current CA is not more than half-way expired or if a forced rotation was not
// requested, and in this case an empty rotation message will be returned.
func maybeRotateSigningSecret(secret *corev1.Secret, currentCACert *x509.Certificate, rawUnsupportedServiceCAConfig []byte) (string, error) {
serviceCAConfig, err := loadUnsupportedServiceCAConfig(rawUnsupportedServiceCAConfig)
reason, err := forceRotationReason(rawUnsupportedServiceCAConfig)
if err != nil {
return "", fmt.Errorf("failed to load unsupportedConfigOverrides: %v", err)
return "", fmt.Errorf("failed to read force rotation reason: %v", err)
}

reason := serviceCAConfig.ForceRotation.Reason
forcedRotation := forcedRotationRequired(secret, reason)

timeBasedRotation := false
if serviceCAConfig.TimeBasedRotation.Enabled {
minimumExpiry := time.Now().Add(minimumTrustDuration)
timeBasedRotation = currentCACert.NotAfter.Before(minimumExpiry)
}
minimumExpiry := time.Now().Add(minimumTrustDuration)
timeBasedRotation := currentCACert.NotAfter.Before(minimumExpiry)

if !(forcedRotation || timeBasedRotation) {
return "", nil
Expand Down Expand Up @@ -193,6 +196,30 @@ func createIntermediateCACert(targetCACert, signingCACert *x509.Certificate, sig
return caCert, nil
}

// forceRotationReason attempts to retrieve a force rotation reason
// from the provided raw UnsupportedConfigOverrides.
func forceRotationReason(rawUnsupportedServiceCAConfig []byte) (string, error) {
serviceCAConfig := &unsupportedServiceCAConfig{}
if raw := rawUnsupportedServiceCAConfig; len(raw) > 0 {
if err := json.Unmarshal(raw, serviceCAConfig); err != nil {
return "", err
}
}

return serviceCAConfig.ForceRotation.Reason, nil
}

// RawUnsupportedServiceCAConfig returns the raw value of the operator field
// UnsupportedConfigOverrides for the given force rotation reason.
func RawUnsupportedServiceCAConfig(reason string) ([]byte, error) {
config := &unsupportedServiceCAConfig{
ForceRotation: forceRotationConfig{
Reason: reason,
},
}
return json.Marshal(config)
}

// forcedRotationRequired indicates whether the force rotation reason is not empty and
// does not match the annotation stored on the signing secret.
func forcedRotationRequired(secret *corev1.Secret, reason string) bool {
Expand Down
10 changes: 3 additions & 7 deletions pkg/operator/rotate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,9 @@ func TestMaybeRotateSigningSecret(t *testing.T) {

for testName, tc := range testCases {
t.Run(testName, func(t *testing.T) {
var rawUnsupportedServiceCAConfig []byte
if len(tc.reason) > 0 || tc.rotationExpected {
var err error
rawUnsupportedServiceCAConfig, err = RawUnsupportedServiceCAConfig(true, tc.reason)
if err != nil {
t.Fatalf("failed to create raw unsupported config overrides: %v", err)
}
rawUnsupportedServiceCAConfig, err := RawUnsupportedServiceCAConfig(tc.reason)
if err != nil {
t.Fatalf("failed to create raw unsupported config overrides: %v", err)
}
secret := tc.secret.DeepCopy()
rotationMessage, err := maybeRotateSigningSecret(secret, tc.caCert, rawUnsupportedServiceCAConfig)
Expand Down
19 changes: 5 additions & 14 deletions test/e2e/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -398,11 +398,6 @@ func triggerTimeBasedRotation(t *testing.T, client *kubernetes.Clientset, config
Key: currentCAKey,
}

// Enable time-based rotation by updating the operator config.
timeBasedRotationEnabled := true
forceRotationReason := ""
setUnsupportedServiceCAConfig(t, config, timeBasedRotationEnabled, forceRotationReason)

// Trigger rotation by renewing the current ca with an expiry that
// is sooner than the minimum required duration.
renewedExpiry := time.Now().Add(1 * time.Hour)
Expand Down Expand Up @@ -447,13 +442,7 @@ func triggerForcedRotation(t *testing.T, client *kubernetes.Clientset, config *r
caCertPEM := secret.Data[v1.TLSCertKey]
caKeyPEM := secret.Data[v1.TLSPrivateKeyKey]

// Trigger a forced rotation by updating the operator config with a reason.
setUnsupportedServiceCAConfig(t, config, false, "42")

pollForCARotation(t, client, caCertPEM, caKeyPEM)
}

func setUnsupportedServiceCAConfig(t *testing.T, config *rest.Config, timeBasedRotationEnabled bool, forceRotationReason string) {
// Trigger a forced rotation by updating the operator config
operatorClient, err := operatorv1client.NewForConfig(config)
if err != nil {
t.Fatalf("error creating operator client: %v", err)
Expand All @@ -462,7 +451,7 @@ func setUnsupportedServiceCAConfig(t *testing.T, config *rest.Config, timeBasedR
if err != nil {
t.Fatalf("error retrieving operator config: %v", err)
}
rawUnsupportedServiceCAConfig, err := operator.RawUnsupportedServiceCAConfig(timeBasedRotationEnabled, forceRotationReason)
rawUnsupportedServiceCAConfig, err := operator.RawUnsupportedServiceCAConfig("42")
if err != nil {
t.Fatalf("failed to create raw unsupported config overrides: %v", err)
}
Expand All @@ -471,6 +460,8 @@ func setUnsupportedServiceCAConfig(t *testing.T, config *rest.Config, timeBasedR
if err != nil {
t.Fatalf("error updating operator config: %v", err)
}

pollForCARotation(t, client, caCertPEM, caKeyPEM)
}

// pollForCARotation polls for the signing secret to be changed in
Expand Down Expand Up @@ -824,7 +815,7 @@ func TestE2E(t *testing.T) {
// validates that both refreshed and unrefreshed clients and
// servers can continue to communicate in a trusted fashion.
t.Run("time-based-ca-rotation", func(t *testing.T) {
checkCARotation(t, adminClient, adminConfig, triggerTimeBasedRotation)
checkCARotation(t, adminClient, nil, triggerTimeBasedRotation)
})

// This test triggers rotation by updating the operator
Expand Down