(ctx context.Context, name string, force, interactive bool)
| 817 | } |
| 818 | |
| 819 | func (cfg *Config) renewCert(ctx context.Context, name string, force, interactive bool) error { |
| 820 | if len(cfg.Issuers) == 0 { |
| 821 | return fmt.Errorf("no issuers configured; impossible to renew or check existing certificate in storage") |
| 822 | } |
| 823 | |
| 824 | log := cfg.Logger.Named("renew") |
| 825 | |
| 826 | name = cfg.transformSubject(ctx, log, name) |
| 827 | |
| 828 | // ensure storage is writeable and readable |
| 829 | // TODO: this is not necessary every time; should only perform check once every so often for each storage, which may require some global state... |
| 830 | err := cfg.checkStorage(ctx) |
| 831 | if err != nil { |
| 832 | return fmt.Errorf("failed storage check: %v - storage is probably misconfigured", err) |
| 833 | } |
| 834 | |
| 835 | log.Info("acquiring lock", zap.String("identifier", name)) |
| 836 | |
| 837 | // ensure idempotency of the renew operation for this name |
| 838 | lockKey := cfg.lockKey(certIssueLockOp, name) |
| 839 | err = acquireLock(ctx, cfg.Storage, lockKey) |
| 840 | if err != nil { |
| 841 | return fmt.Errorf("unable to acquire lock '%s': %v", lockKey, err) |
| 842 | } |
| 843 | defer func() { |
| 844 | log.Info("releasing lock", zap.String("identifier", name)) |
| 845 | |
| 846 | if err := releaseLock(ctx, cfg.Storage, lockKey); err != nil { |
| 847 | log.Error("unable to unlock", |
| 848 | zap.String("identifier", name), |
| 849 | zap.String("lock_key", lockKey), |
| 850 | zap.Error(err)) |
| 851 | } |
| 852 | }() |
| 853 | log.Info("lock acquired", zap.String("identifier", name)) |
| 854 | |
| 855 | f := func(ctx context.Context) error { |
| 856 | // renew lease on the certificate store lock if the store implementation supports it; |
| 857 | // prevents the lock from being acquired by another process/instance while we're renewing |
| 858 | attempt, ok := ctx.Value(AttemptsCtxKey).(*int) |
| 859 | if ok { |
| 860 | err = cfg.renewLockLease(ctx, cfg.Storage, lockKey, *attempt) |
| 861 | if err != nil { |
| 862 | return fmt.Errorf("unable to renew lock lease '%s': %v", lockKey, err) |
| 863 | } |
| 864 | } |
| 865 | |
| 866 | // prepare for renewal (load PEM cert, key, and meta) |
| 867 | certRes, err := cfg.loadCertResourceAnyIssuer(ctx, name) |
| 868 | if err != nil { |
| 869 | return err |
| 870 | } |
| 871 | |
| 872 | // check if renew is still needed - might have been renewed while waiting for lock |
| 873 | timeLeft, leaf, needsRenew := cfg.managedCertNeedsRenewal(certRes, false) |
| 874 | if !needsRenew { |
| 875 | if force { |
| 876 | log.Info("certificate does not need to be renewed, but renewal is being forced", |
no test coverage detected