@@ -17,6 +17,7 @@ package certmanager
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/getprobo/probo/pkg/coredata"
|
"github.com/getprobo/probo/pkg/coredata"
|
||||||
@@ -111,6 +112,44 @@ func (p *Provisioner) checkPendingDomains(ctx context.Context) error {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isChallengeFailedError(err error) bool {
|
||||||
|
if err == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
errStr := strings.ToLower(err.Error())
|
||||||
|
|
||||||
|
// These errors indicate the challenge/order is no longer valid
|
||||||
|
return strings.Contains(errStr, "authorization must be pending") ||
|
||||||
|
strings.Contains(errStr, "order") && strings.Contains(errStr, "invalid") ||
|
||||||
|
strings.Contains(errStr, "authorization") && strings.Contains(errStr, "invalid") ||
|
||||||
|
strings.Contains(errStr, "challenge") && strings.Contains(errStr, "invalid")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Provisioner) resetDomainToRetry(
|
||||||
|
ctx context.Context,
|
||||||
|
conn pg.Conn,
|
||||||
|
domain *coredata.CustomDomain,
|
||||||
|
) error {
|
||||||
|
fullDomain := &coredata.CustomDomain{}
|
||||||
|
if err := fullDomain.LoadByIDForUpdate(ctx, conn, coredata.NewNoScope(), p.encryptionKey, domain.ID); err != nil {
|
||||||
|
return fmt.Errorf("cannot load domain for update: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fullDomain.HTTPChallengeToken = nil
|
||||||
|
fullDomain.HTTPChallengeKeyAuth = nil
|
||||||
|
fullDomain.HTTPChallengeURL = nil
|
||||||
|
fullDomain.HTTPOrderURL = nil
|
||||||
|
|
||||||
|
fullDomain.SSLStatus = coredata.CustomDomainSSLStatusPending
|
||||||
|
|
||||||
|
if err := fullDomain.Update(ctx, conn, coredata.NewNoScope(), p.encryptionKey); err != nil {
|
||||||
|
return fmt.Errorf("cannot update domain: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Provisioner) provisionDomainCertificate(
|
func (p *Provisioner) provisionDomainCertificate(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
conn pg.Conn,
|
conn pg.Conn,
|
||||||
@@ -172,6 +211,32 @@ func (p *Provisioner) provisionDomainCertificate(
|
|||||||
log.Error(err),
|
log.Error(err),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Check if the error indicates the challenge/order has failed
|
||||||
|
// and needs to be reset for a fresh attempt
|
||||||
|
if isChallengeFailedError(err) {
|
||||||
|
p.logger.InfoCtx(
|
||||||
|
ctx,
|
||||||
|
"challenge or order is no longer valid, resetting domain to retry with fresh challenge",
|
||||||
|
log.String("domain", domain.Domain),
|
||||||
|
)
|
||||||
|
|
||||||
|
if resetErr := p.resetDomainToRetry(ctx, conn, domain); resetErr != nil {
|
||||||
|
p.logger.ErrorCtx(
|
||||||
|
ctx,
|
||||||
|
"cannot reset domain for retry",
|
||||||
|
log.String("domain", domain.Domain),
|
||||||
|
log.Error(resetErr),
|
||||||
|
)
|
||||||
|
return resetErr
|
||||||
|
}
|
||||||
|
|
||||||
|
p.logger.InfoCtx(
|
||||||
|
ctx,
|
||||||
|
"domain reset to pending, will retry with new challenge on next cycle",
|
||||||
|
log.String("domain", domain.Domain),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user