Put SSLStatus not nullable
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,24 +30,24 @@ import (
|
|||||||
|
|
||||||
type (
|
type (
|
||||||
CustomDomain struct {
|
CustomDomain struct {
|
||||||
ID gid.GID `db:"id"`
|
ID gid.GID `db:"id"`
|
||||||
OrganizationID gid.GID `db:"organization_id"`
|
OrganizationID gid.GID `db:"organization_id"`
|
||||||
Domain string `db:"domain"`
|
Domain string `db:"domain"`
|
||||||
HTTPChallengeToken *string `db:"http_challenge_token"`
|
HTTPChallengeToken *string `db:"http_challenge_token"`
|
||||||
HTTPChallengeKeyAuth *string `db:"http_challenge_key_auth"`
|
HTTPChallengeKeyAuth *string `db:"http_challenge_key_auth"`
|
||||||
HTTPChallengeURL *string `db:"http_challenge_url"`
|
HTTPChallengeURL *string `db:"http_challenge_url"`
|
||||||
HTTPOrderURL *string `db:"http_order_url"`
|
HTTPOrderURL *string `db:"http_order_url"`
|
||||||
SSLCertificate *tls.Certificate `db:"-"` // Parsed certificate
|
SSLCertificate *tls.Certificate `db:"-"` // Parsed certificate
|
||||||
SSLCertificatePEM []byte `db:"-"` // Decrypted PEM
|
SSLCertificatePEM []byte `db:"-"` // Decrypted PEM
|
||||||
EncryptedSSLCertificate []byte `db:"encrypted_ssl_certificate"`
|
EncryptedSSLCertificate []byte `db:"encrypted_ssl_certificate"`
|
||||||
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"`
|
||||||
UpdatedAt time.Time `db:"updated_at"`
|
UpdatedAt time.Time `db:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomDomains []*CustomDomain
|
CustomDomains []*CustomDomain
|
||||||
@@ -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())
|
||||||
|
|||||||
Reference in New Issue
Block a user