package certificates import ( "time" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) // RenewalTimeFunc is a custom function type for calculating renewal time of a certificate. type RenewalTimeFunc func(time.Time, time.Time, *metav1.Duration) *metav1.Time // RenewalTime calculates renewal time for a certificate. Default renewal time // is 2/3 through certificate's lifetime. If user has configured // spec.renewBefore, renewal time will be renewBefore period before expiry // (unless that is after the expiry). func RenewalTime(notBefore, notAfter time.Time, renewBeforeOverride *metav1.Duration) *metav1.Time { // 1. Calculate how long before expiry a cert should be renewed actualDuration := notAfter.Sub(notBefore) renewBefore := actualDuration / 3 // If spec.renewBefore was set (and is less than duration) // respect that. We don't want to prevent users from renewing // longer lived certs more frequently. if renewBeforeOverride != nil && renewBeforeOverride.Duration < actualDuration { renewBefore = renewBeforeOverride.Duration } // 2. Calculate when a cert should be renewed // Truncate the renewal time to nearest second. This is important // because the renewal time also gets stored on Certificate's status // where it is truncated to the nearest second. We use the renewal time // from Certificate's status to determine when the Certificate will be // added to the queue to be renewed, but then re-calculate whether it // needs to be renewed _now_ using this function- so returning a // non-truncated value here would potentially cause Certificates to be // re-queued for renewal earlier than the calculated renewal time thus // causing Certificates to not be automatically renewed. See // https://github.com/cert-manager/cert-manager/pull/4399. rt := metav1.NewTime(notAfter.Add(-1 * renewBefore).Truncate(time.Second)) return &rt }