MCPcopy
hub / github.com/caddyserver/certmagic / updateARI

Method updateARI

maintain.go:459–624  ·  view source on GitHub ↗

updateARI updates the cert's ACME renewal info, first by checking storage for a newer one, or getting it from the CA if needed. The updated info is stored in storage and updated in the cache. The certificate with the updated ARI is returned. If true is returned, the ARI window or selected time has c

(ctx context.Context, cert Certificate, logger *zap.Logger)

Source from the content-addressed store, hash-verified

457// This will always try to ARI without checking if it needs to be refreshed. Call
458// NeedsRefresh() on the RenewalInfo first, and only call this if that returns true.
459func (cfg *Config) updateARI(ctx context.Context, cert Certificate, logger *zap.Logger) (updatedCert Certificate, changed bool, err error) {
460 logger = logger.With(
461 zap.Strings("identifiers", cert.Names),
462 zap.String("cert_hash", cert.hash),
463 zap.String("ari_unique_id", cert.ari.UniqueIdentifier),
464 zap.Time("cert_expiry", cert.Leaf.NotAfter))
465
466 updatedCert = cert
467 oldARI := cert.ari
468
469 // synchronize ARI fetching; see #297
470 lockName := "ari_" + cert.ari.UniqueIdentifier
471 if _, ok := cfg.Storage.(TryLocker); ok {
472 ok, err := tryAcquireLock(ctx, cfg.Storage, lockName)
473 if err != nil {
474 return cert, false, fmt.Errorf("unable to obtain ARI lock: %v", err)
475 }
476 if !ok {
477 logger.Debug("attempted to obtain ARI lock but it was already taken")
478 return cert, false, nil
479 }
480 } else if err := acquireLock(ctx, cfg.Storage, lockName); err != nil {
481 return cert, false, fmt.Errorf("unable to obtain ARI lock: %v", err)
482 }
483 defer func() {
484 if err := releaseLock(ctx, cfg.Storage, lockName); err != nil {
485 logger.Error("unable to release ARI lock", zap.Error(err))
486 }
487 }()
488
489 // see if the stored value has been refreshed already by another instance
490 gotNewARI, newARI, err := cfg.storageHasNewerARI(ctx, cert)
491
492 // when we're all done, log if something about the schedule is different
493 // ("WARN" level because ARI window changing may be a sign of external trouble
494 // and we want to draw their attention to a potential explanation URL)
495 defer func() {
496 changed = !newARI.SameWindow(oldARI)
497
498 if changed {
499 logger.Warn("ARI window or selected renewal time changed",
500 zap.Time("prev_start", oldARI.SuggestedWindow.Start),
501 zap.Time("next_start", newARI.SuggestedWindow.Start),
502 zap.Time("prev_end", oldARI.SuggestedWindow.End),
503 zap.Time("next_end", newARI.SuggestedWindow.End),
504 zap.Time("prev_selected_time", oldARI.SelectedTime),
505 zap.Time("next_selected_time", newARI.SelectedTime),
506 zap.String("explanation_url", newARI.ExplanationURL))
507 }
508 }()
509
510 if err == nil && gotNewARI {
511 // great, storage has a newer one we can use
512 cfg.certCache.mu.Lock()
513 var ok bool
514 updatedCert, ok = cfg.certCache.cache[cert.hash]
515 if !ok {
516 // cert is no longer in the cache... why? what's the right thing to do here?

Callers 3

manageOneMethod · 0.95
handshakeMaintenanceMethod · 0.95

Calls 13

storageHasNewerARIMethod · 0.95
tryAcquireLockFunction · 0.85
acquireLockFunction · 0.85
releaseLockFunction · 0.85
StringMethod · 0.80
ErrorMethod · 0.80
SiteMetaMethod · 0.80
LockMethod · 0.65
UnlockMethod · 0.65
IssuerKeyMethod · 0.65
GetRenewalInfoMethod · 0.65

Tested by

no test coverage detected