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)
| 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. |
| 459 | func (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? |
no test coverage detected