Cleanup frees up resources allocated during Provision.
()
| 476 | |
| 477 | // Cleanup frees up resources allocated during Provision. |
| 478 | func (t *TLS) Cleanup() error { |
| 479 | // stop the session ticket rotation goroutine |
| 480 | if t.SessionTickets != nil { |
| 481 | t.SessionTickets.stop() |
| 482 | } |
| 483 | |
| 484 | // if a new TLS app was loaded, remove certificates from the cache that are no longer |
| 485 | // being managed or loaded by the new config; if there is no more TLS app running, |
| 486 | // then stop cert maintenance and let the cert cache be GC'ed |
| 487 | if nextTLS, err := caddy.ActiveContext().AppIfConfigured("tls"); err == nil && nextTLS != nil { |
| 488 | nextTLSApp := nextTLS.(*TLS) |
| 489 | |
| 490 | // compute which certificates were managed or loaded into the cert cache by this |
| 491 | // app instance (which is being stopped) that are not managed or loaded by the |
| 492 | // new app instance (which just started), and remove them from the cache |
| 493 | var noLongerManaged []certmagic.SubjectIssuer |
| 494 | var noLongerLoaded []string |
| 495 | reManage := make(map[string]struct{}) |
| 496 | for subj, currentIssuerKey := range t.managing { |
| 497 | // It's a bit nuanced: managed certs can sometimes be different enough that we have to |
| 498 | // swap them out for a different one, even if they are for the same subject/domain. |
| 499 | // We consider "private" certs (internal CA/locally-trusted/etc) to be significantly |
| 500 | // distinct from "public" certs (production CAs/globally-trusted/etc) because of the |
| 501 | // implications when it comes to actual deployments: switching between an internal CA |
| 502 | // and a production CA, for example, is quite significant. Switching from one public CA |
| 503 | // to another, however, is not, and for our purposes we consider those to be the same. |
| 504 | // Anyway, if the next TLS app does not manage a cert for this name at all, definitely |
| 505 | // remove it from the cache. But if it does, and it's not the same kind of issuer/CA |
| 506 | // as we have, also remove it, so that it can swap it out for the right one. |
| 507 | if nextIssuerKey, ok := nextTLSApp.managing[subj]; !ok || nextIssuerKey != currentIssuerKey { |
| 508 | // next app is not managing a cert for this domain at all or is using a different issuer, so remove it |
| 509 | noLongerManaged = append(noLongerManaged, certmagic.SubjectIssuer{Subject: subj, IssuerKey: currentIssuerKey}) |
| 510 | |
| 511 | // then, if the next app is managing a cert for this name, but with a different issuer, re-manage it |
| 512 | if ok && nextIssuerKey != currentIssuerKey { |
| 513 | reManage[subj] = struct{}{} |
| 514 | } |
| 515 | } |
| 516 | } |
| 517 | for hash := range t.loaded { |
| 518 | if _, ok := nextTLSApp.loaded[hash]; !ok { |
| 519 | noLongerLoaded = append(noLongerLoaded, hash) |
| 520 | } |
| 521 | } |
| 522 | |
| 523 | // remove the certs |
| 524 | certCacheMu.RLock() |
| 525 | certCache.RemoveManaged(noLongerManaged) |
| 526 | certCache.Remove(noLongerLoaded) |
| 527 | certCacheMu.RUnlock() |
| 528 | |
| 529 | // give the new TLS app a "kick" to manage certs that it is configured for |
| 530 | // with its own configuration instead of the one we just evicted |
| 531 | if err := nextTLSApp.Manage(reManage); err != nil { |
| 532 | if c := t.logger.Check(zapcore.ErrorLevel, "re-managing unloaded certificates with new config"); c != nil { |
| 533 | c.Write( |
| 534 | zap.Strings("subjects", internal.MaxSizeSubjectsListForLog(reManage, 1000)), |
| 535 | zap.Error(err), |
nothing calls this directly
no test coverage detected