Put SSLStatus not nullable

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
This commit is contained in:
Bryan Frimin
2025-10-01 00:09:23 +02:00
parent 332b7faa5b
commit 06d64ae999
4 changed files with 73 additions and 33 deletions

View File

@@ -85,7 +85,7 @@ func (p *Provisioner) checkPendingDomains(ctx context.Context) error {
return nil return nil
} }
p.logger.InfoCtx(ctx, "found domains with pending challenges", log.Int("count", len(domains))) p.logger.InfoCtx(ctx, "found domains needing SSL provisioning", log.Int("count", len(domains)))
for _, domain := range domains { for _, domain := range domains {
select { select {
@@ -94,10 +94,10 @@ func (p *Provisioner) checkPendingDomains(ctx context.Context) error {
default: default:
} }
if err := p.completeDomainCertificate(ctx, conn, domain); err != nil { if err := p.provisionDomainCertificate(ctx, conn, domain); err != nil {
p.logger.ErrorCtx( p.logger.ErrorCtx(
ctx, ctx,
"cannot complete certificate for domain", "cannot provision certificate for domain",
log.String("domain", domain.Domain), log.String("domain", domain.Domain),
log.Error(err), log.Error(err),
) )
@@ -108,11 +108,53 @@ func (p *Provisioner) checkPendingDomains(ctx context.Context) error {
}) })
} }
func (p *Provisioner) completeDomainCertificate( func (p *Provisioner) provisionDomainCertificate(
ctx context.Context, ctx context.Context,
conn pg.Conn, conn pg.Conn,
domain *coredata.CustomDomain, domain *coredata.CustomDomain,
) error { ) error {
if domain.SSLStatus == coredata.CustomDomainSSLStatusPending {
p.logger.InfoCtx(ctx, "initiating HTTP challenge for domain", log.String("domain", domain.Domain))
challenge, err := p.acmeService.GetHTTPChallenge(ctx, domain.Domain)
if err != nil {
p.logger.ErrorCtx(
ctx,
"failed to get HTTP challenge",
log.String("domain", domain.Domain),
log.Error(err),
)
return err
}
// Update domain with challenge details and set to PROVISIONING
scope := coredata.NewScope(domain.OrganizationID.TenantID())
fullDomain := &coredata.CustomDomain{}
if err := fullDomain.LoadByIDForUpdate(ctx, conn, scope, p.encryptionKey, domain.ID); err != nil {
return fmt.Errorf("cannot load domain for update: %w", err)
}
fullDomain.HTTPChallengeToken = &challenge.Token
fullDomain.HTTPChallengeKeyAuth = &challenge.KeyAuth
fullDomain.HTTPChallengeURL = &challenge.URL
fullDomain.HTTPOrderURL = &challenge.OrderURL
fullDomain.SSLStatus = coredata.CustomDomainSSLStatusProvisioning
if err := fullDomain.Update(ctx, conn, scope, p.encryptionKey); err != nil {
return fmt.Errorf("failed to update domain with challenge: %w", err)
}
p.logger.InfoCtx(
ctx,
"HTTP challenge initiated, will complete in next cycle",
log.String("domain", domain.Domain),
log.String("token", challenge.Token),
)
return nil
}
// Domain already has challenge details, complete it
challenge := &HTTPChallenge{ challenge := &HTTPChallenge{
Domain: domain.Domain, Domain: domain.Domain,
Token: *domain.HTTPChallengeToken, Token: *domain.HTTPChallengeToken,
@@ -151,8 +193,7 @@ func (p *Provisioner) completeDomainCertificate(
chainStr := string(cert.ChainPEM) chainStr := string(cert.ChainPEM)
fullDomain.SSLCertificateChain = &chainStr fullDomain.SSLCertificateChain = &chainStr
fullDomain.SSLExpiresAt = &cert.ExpiresAt fullDomain.SSLExpiresAt = &cert.ExpiresAt
status := coredata.CustomDomainSSLStatusActive fullDomain.SSLStatus = coredata.CustomDomainSSLStatusActive
fullDomain.SSLStatus = &status
fullDomain.HTTPChallengeToken = nil fullDomain.HTTPChallengeToken = nil
fullDomain.HTTPChallengeKeyAuth = nil fullDomain.HTTPChallengeKeyAuth = nil

View File

@@ -24,7 +24,6 @@ import (
"github.com/getprobo/probo/pkg/crypto/cipher" "github.com/getprobo/probo/pkg/crypto/cipher"
"go.gearno.de/kit/log" "go.gearno.de/kit/log"
"go.gearno.de/kit/pg" "go.gearno.de/kit/pg"
"go.gearno.de/x/ref"
) )
type ( type (
@@ -136,7 +135,7 @@ func (r *Renewer) renewDomain(ctx context.Context, conn pg.Conn, domain *coredat
return fmt.Errorf("cannot lock domain for renewal: %w", err) return fmt.Errorf("cannot lock domain for renewal: %w", err)
} }
if lockedDomain.SSLStatus == nil || *lockedDomain.SSLStatus != coredata.CustomDomainSSLStatusActive { if lockedDomain.SSLStatus != coredata.CustomDomainSSLStatusActive {
r.logger.InfoCtx( r.logger.InfoCtx(
ctx, ctx,
"domain status changed, skipping renewal", "domain status changed, skipping renewal",
@@ -164,7 +163,7 @@ func (r *Renewer) renewDomain(ctx context.Context, conn pg.Conn, domain *coredat
lockedDomain.HTTPChallengeKeyAuth = &challenge.KeyAuth lockedDomain.HTTPChallengeKeyAuth = &challenge.KeyAuth
lockedDomain.HTTPChallengeURL = &challenge.URL lockedDomain.HTTPChallengeURL = &challenge.URL
lockedDomain.HTTPOrderURL = &challenge.OrderURL lockedDomain.HTTPOrderURL = &challenge.OrderURL
lockedDomain.SSLStatus = ref.Ref(coredata.CustomDomainSSLStatusRenewing) lockedDomain.SSLStatus = coredata.CustomDomainSSLStatusRenewing
if err := lockedDomain.Update(ctx, conn, scope, r.encryptionKey); err != nil { if err := lockedDomain.Update(ctx, conn, scope, r.encryptionKey); err != nil {
return fmt.Errorf("cannot update domain with renewal challenge: %w", err) return fmt.Errorf("cannot update domain with renewal challenge: %w", err)
@@ -189,7 +188,7 @@ func (r *Renewer) renewDomain(ctx context.Context, conn pg.Conn, domain *coredat
chainStr := string(cert.ChainPEM) chainStr := string(cert.ChainPEM)
lockedDomain.SSLCertificateChain = &chainStr lockedDomain.SSLCertificateChain = &chainStr
lockedDomain.SSLExpiresAt = &cert.ExpiresAt lockedDomain.SSLExpiresAt = &cert.ExpiresAt
lockedDomain.SSLStatus = ref.Ref(coredata.CustomDomainSSLStatusActive) lockedDomain.SSLStatus = coredata.CustomDomainSSLStatusActive
lockedDomain.HTTPChallengeToken = nil lockedDomain.HTTPChallengeToken = nil
lockedDomain.HTTPChallengeKeyAuth = nil lockedDomain.HTTPChallengeKeyAuth = nil

View File

@@ -118,7 +118,7 @@ func (s *Selector) rebuildCacheEntry(ctx context.Context, conn pg.Conn, domain s
return fmt.Errorf("domain is not active") return fmt.Errorf("domain is not active")
} }
if customDomain.SSLStatus == nil || *customDomain.SSLStatus != coredata.CustomDomainSSLStatusActive { if customDomain.SSLStatus != coredata.CustomDomainSSLStatusActive {
return fmt.Errorf("domain does not have active SSL certificate") return fmt.Errorf("domain does not have active SSL certificate")
} }

View File

@@ -43,7 +43,7 @@ type (
SSLPrivateKeyPEM []byte `db:"-"` // Decrypted PEM SSLPrivateKeyPEM []byte `db:"-"` // Decrypted PEM
EncryptedSSLPrivateKey []byte `db:"encrypted_ssl_private_key"` EncryptedSSLPrivateKey []byte `db:"encrypted_ssl_private_key"`
SSLCertificateChain *string `db:"ssl_certificate_chain"` SSLCertificateChain *string `db:"ssl_certificate_chain"`
SSLStatus *CustomDomainSSLStatus `db:"ssl_status"` SSLStatus CustomDomainSSLStatus `db:"ssl_status"`
SSLExpiresAt *time.Time `db:"ssl_expires_at"` SSLExpiresAt *time.Time `db:"ssl_expires_at"`
IsActive bool `db:"is_active"` IsActive bool `db:"is_active"`
CreatedAt time.Time `db:"created_at"` CreatedAt time.Time `db:"created_at"`
@@ -762,10 +762,10 @@ WHERE
q = fmt.Sprintf(q, scope.SQLFragment()) q = fmt.Sprintf(q, scope.SQLFragment())
args := pgx.NamedArgs{ args := pgx.NamedArgs{
"statuses": []CustomDomainSSLStatus{ "statuses": []string{
CustomDomainSSLStatusPending, string(CustomDomainSSLStatusPending),
CustomDomainSSLStatusProvisioning, string(CustomDomainSSLStatusProvisioning),
CustomDomainSSLStatusRenewing, string(CustomDomainSSLStatusRenewing),
}, },
} }
maps.Copy(args, scope.SQLArguments()) maps.Copy(args, scope.SQLArguments())