Skip to content

Commit

Permalink
feat: dynamic certificate expiration deadline (#615)
Browse files Browse the repository at this point in the history
* feat: dynamic certificate expiration deadline

Signed-off-by: Dario Tranchitella <[email protected]>

* docs: dynamic certificate expiration deadline

Signed-off-by: Dario Tranchitella <[email protected]>

---------

Signed-off-by: Dario Tranchitella <[email protected]>
  • Loading branch information
prometherion authored Oct 25, 2024
1 parent 4e8c2b6 commit 12248de
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 20 deletions.
38 changes: 22 additions & 16 deletions cmd/manager/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,21 +41,22 @@ import (
func NewCmd(scheme *runtime.Scheme) *cobra.Command {
// CLI flags
var (
metricsBindAddress string
healthProbeBindAddress string
leaderElect bool
tmpDirectory string
kineImage string
controllerReconcileTimeout time.Duration
cacheResyncPeriod time.Duration
datastore string
managerNamespace string
managerServiceAccountName string
managerServiceName string
webhookCABundle []byte
migrateJobImage string
maxConcurrentReconciles int
disableTelemetry bool
metricsBindAddress string
healthProbeBindAddress string
leaderElect bool
tmpDirectory string
kineImage string
controllerReconcileTimeout time.Duration
cacheResyncPeriod time.Duration
datastore string
managerNamespace string
managerServiceAccountName string
managerServiceName string
webhookCABundle []byte
migrateJobImage string
maxConcurrentReconciles int
disableTelemetry bool
certificateExpirationDeadline time.Duration

webhookCAPath string
)
Expand All @@ -76,6 +77,10 @@ func NewCmd(scheme *runtime.Scheme) *cobra.Command {
return err
}

if certificateExpirationDeadline < 24*time.Hour {
return fmt.Errorf("certificate expiration deadline must be at least 24 hours")
}

if webhookCABundle, err = os.ReadFile(webhookCAPath); err != nil {
return fmt.Errorf("unable to read webhook CA: %w", err)
}
Expand Down Expand Up @@ -186,7 +191,7 @@ func NewCmd(scheme *runtime.Scheme) *cobra.Command {
}
}

if err = (&controllers.CertificateLifecycle{Channel: certChannel}).SetupWithManager(mgr); err != nil {
if err = (&controllers.CertificateLifecycle{Channel: certChannel, Deadline: certificateExpirationDeadline}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "CertificateLifecycle")

return err
Expand Down Expand Up @@ -309,6 +314,7 @@ func NewCmd(scheme *runtime.Scheme) *cobra.Command {
cmd.Flags().DurationVar(&controllerReconcileTimeout, "controller-reconcile-timeout", 30*time.Second, "The reconciliation request timeout before the controller withdraw the external resource calls, such as dealing with the Datastore, or the Tenant Control Plane API endpoint.")
cmd.Flags().DurationVar(&cacheResyncPeriod, "cache-resync-period", 10*time.Hour, "The controller-runtime.Manager cache resync period.")
cmd.Flags().BoolVar(&disableTelemetry, "disable-telemetry", false, "Disable the analytics traces collection.")
cmd.Flags().DurationVar(&certificateExpirationDeadline, "certificate-expiration-deadline", 24*time.Hour, "Define the deadline upon certificate expiration to start the renewal process, cannot be less than a 24 hours.")

cobra.OnInitialize(func() {
viper.AutomaticEnv()
Expand Down
8 changes: 5 additions & 3 deletions controllers/certificate_lifecycle_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ import (
)

type CertificateLifecycle struct {
Channel CertificateChannel
client client.Client
Channel CertificateChannel
Deadline time.Duration

client client.Client
}

func (s *CertificateLifecycle) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) {
Expand Down Expand Up @@ -76,7 +78,7 @@ func (s *CertificateLifecycle) Reconcile(ctx context.Context, request reconcile.
return reconcile.Result{}, nil
}

deadline := time.Now().AddDate(0, 0, 1)
deadline := time.Now().Add(s.Deadline)

if deadline.After(crt.NotAfter) {
logger.Info("certificate near expiration, must be rotated")
Expand Down
5 changes: 4 additions & 1 deletion docs/content/guides/certs-lifecycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,10 @@ k8s-126-576c775b5d-jmvlm 4/4 Running 0 50s
The Kamaji operator will run a controller which processes all the Secrets to determine their expiration, both for the `kubeconfig`, as well as for the certificates.

The controller, named `CertificateLifecycle`, will extract the certificates from the _Secret_ objects notifying the `TenantControlPlaneReconciler` controller which will start a new certificate rotation.
The rotation will occur the day before their expiration.
By default, the rotation will occur the day before their expiration.

This rotation deadline can be dynamically configured using the Kamaji CLI flag `--certificate-expiration-deadline` using the Go _Duration_ syntax:
e.g.: set the value `7d` to trigger the renewal a week before the effective expiration date.

> Nota Bene:
>
Expand Down

0 comments on commit 12248de

Please sign in to comment.