(ctx context.Context, name string, interactive bool)
| 545 | } |
| 546 | |
| 547 | func (cfg *Config) obtainCert(ctx context.Context, name string, interactive bool) error { |
| 548 | if len(cfg.Issuers) == 0 { |
| 549 | return fmt.Errorf("no issuers configured; impossible to obtain or check for existing certificate in storage") |
| 550 | } |
| 551 | |
| 552 | log := cfg.Logger.Named("obtain") |
| 553 | |
| 554 | name = cfg.transformSubject(ctx, log, name) |
| 555 | |
| 556 | // if storage has all resources for this certificate, obtain is a no-op |
| 557 | if cfg.storageHasCertResourcesAnyIssuer(ctx, name) { |
| 558 | return nil |
| 559 | } |
| 560 | |
| 561 | // ensure storage is writeable and readable |
| 562 | // TODO: this is not necessary every time; should only perform check once every so often for each storage, which may require some global state... |
| 563 | err := cfg.checkStorage(ctx) |
| 564 | if err != nil { |
| 565 | return fmt.Errorf("failed storage check: %v - storage is probably misconfigured", err) |
| 566 | } |
| 567 | |
| 568 | log.Info("acquiring lock", zap.String("identifier", name)) |
| 569 | |
| 570 | // ensure idempotency of the obtain operation for this name |
| 571 | lockKey := cfg.lockKey(certIssueLockOp, name) |
| 572 | err = acquireLock(ctx, cfg.Storage, lockKey) |
| 573 | if err != nil { |
| 574 | return fmt.Errorf("unable to acquire lock '%s': %v", lockKey, err) |
| 575 | } |
| 576 | defer func() { |
| 577 | log.Info("releasing lock", zap.String("identifier", name)) |
| 578 | if err := releaseLock(ctx, cfg.Storage, lockKey); err != nil { |
| 579 | log.Error("unable to unlock", |
| 580 | zap.String("identifier", name), |
| 581 | zap.String("lock_key", lockKey), |
| 582 | zap.Error(err)) |
| 583 | } |
| 584 | }() |
| 585 | log.Info("lock acquired", zap.String("identifier", name)) |
| 586 | |
| 587 | f := func(ctx context.Context) error { |
| 588 | // renew lease on the lock if the certificate store supports it |
| 589 | attempt, ok := ctx.Value(AttemptsCtxKey).(*int) |
| 590 | if ok { |
| 591 | err = cfg.renewLockLease(ctx, cfg.Storage, lockKey, *attempt) |
| 592 | if err != nil { |
| 593 | return fmt.Errorf("unable to renew lock lease '%s': %v", lockKey, err) |
| 594 | } |
| 595 | } |
| 596 | |
| 597 | // check if obtain is still needed -- might have been obtained during lock |
| 598 | if cfg.storageHasCertResourcesAnyIssuer(ctx, name) { |
| 599 | log.Info("certificate already exists in storage", zap.String("identifier", name)) |
| 600 | return nil |
| 601 | } |
| 602 | |
| 603 | log.Info("obtaining certificate", zap.String("identifier", name)) |
| 604 |
no test coverage detected