Swap cert renewal to use notifier
ci/woodpecker/push/build Pipeline was successful Details

This commit is contained in:
Melon 2023-03-12 02:54:47 +00:00
parent 21df52fafb
commit 3e9db544f1
Signed by: melon
GPG Key ID: 6C9D970C50D26A25
2 changed files with 32 additions and 20 deletions

View File

@ -3,12 +3,14 @@ package main
import (
"code.mrmelon54.com/melon/summer/cmd/buttercup/api"
"code.mrmelon54.com/melon/summer/pkg/cli"
"code.mrmelon54.com/melon/summer/pkg/notifier"
"code.mrmelon54.com/melon/summer/pkg/renewal"
"code.mrmelon54.com/melon/summer/pkg/tables/certificate"
renewal2 "code.mrmelon54.com/melon/summer/pkg/tables/renewal"
"code.mrmelon54.com/melon/summer/pkg/tables/web"
"code.mrmelon54.com/melon/summer/pkg/utils"
"github.com/mrmelon54/mjwt"
"log"
"net/http"
"sync"
)
@ -43,10 +45,13 @@ func (buttercup *Buttercup) Init(runner *cli.Runner[ButtercupConfig]) {
var err error
buttercup.verify, err = mjwt.NewMJwtVerifierFromFile(buttercup.conf.Auth.Public)
utils.Check("[Buttercup.Init()] Failed to load verifier public key", err)
notify, err := notifier.Init(buttercup.conf.Notify)
utils.Check("[Buttercup.Init()] Failed to load notifier", err)
log.Printf("[Buttercup.Init()] Using LetsEncrypt directory: %s\n", buttercup.conf.Renewal.LetsEncrypt.Directory)
buttercup.renewalWg = &sync.WaitGroup{}
provider := renewal.NewCustomHTTPProvider(runner.Database)
buttercup.renewal = renewal.NewRenewalService(buttercup.renewalWg, runner.Database, provider, buttercup.conf.Renewal)
buttercup.renewal = renewal.NewRenewalService(buttercup.renewalWg, runner.Database, provider, buttercup.conf.Renewal, notify)
buttercup.apiServer = api.NewApiServer(buttercup.conf.Listen, runner.Database, buttercup.renewal, buttercup.verify)
}

View File

@ -2,6 +2,7 @@ package renewal
import (
pebbleDev "code.mrmelon54.com/melon/summer/cmd/buttercup/pebble-dev"
"code.mrmelon54.com/melon/summer/pkg/notifier"
certificate2 "code.mrmelon54.com/melon/summer/pkg/tables/certificate"
"code.mrmelon54.com/melon/summer/pkg/tables/renewal"
"code.mrmelon54.com/melon/summer/pkg/utils"
@ -9,6 +10,7 @@ import (
"crypto/tls"
"crypto/x509"
"encoding/pem"
"fmt"
"github.com/go-acme/lego/v4/certificate"
"github.com/go-acme/lego/v4/lego"
"github.com/go-acme/lego/v4/providers/dns/namesilo"
@ -33,6 +35,7 @@ type Renewal struct {
caAddr string
caCert []byte
renewLock *sync.Mutex
notify notifier.Notifier
}
type MyAccount struct {
@ -53,12 +56,18 @@ func (u *MyAccount) GetPrivateKey() crypto.PrivateKey {
return u.key
}
func NewRenewalService(wg *sync.WaitGroup, db *xorm.Engine, httpProvider *CustomHTTPProvider, config Config) *Renewal {
r := &Renewal{db: db, httpProvider: httpProvider, renewLock: &sync.Mutex{}}
func NewRenewalService(wg *sync.WaitGroup, db *xorm.Engine, httpProvider *CustomHTTPProvider, config Config, notify notifier.Notifier) *Renewal {
r := &Renewal{db: db, httpProvider: httpProvider, renewLock: &sync.Mutex{}, notify: notify}
r.load(wg, config)
return r
}
func (r *Renewal) logf(format string, v ...any) {
s := strings.TrimSpace(fmt.Sprintf(format, v...))
log.Println(s)
r.notify.SendMessage(s)
}
func (r *Renewal) load(wg *sync.WaitGroup, config Config) {
r.certTicker = time.NewTicker(time.Hour * 4)
r.certDone = make(chan struct{})
@ -140,12 +149,12 @@ select * from certificate
where active = 1 and auto_renew = 1 and renewing = 0 and renew_failed = 0 and data_id IS NULL
`).Find(&certs)
if err != nil {
log.Printf("[Renewal::renewalCheck()] Failed to get certificates for a renewal check: %s\n", err)
r.logf("[Renewal::renewalCheck()] Failed to get certificates for a renewal check: %s", err)
return nil
}
for _, i := range certs {
log.Printf("[Renewal] Cert '%d' runs out in 30 days\n", i.Id)
r.logf("[Renewal] Cert '%d' runs out in 30 days", i.Id)
r.RequestUpdate(i)
}
@ -156,11 +165,11 @@ func (r *Renewal) RequestUpdate(c certificate2.CertificateMetaDomainJoiner) {
var a []certificate2.CertificateData
err := r.db.Where("previous_cert = ?", c.Id).Limit(1).Find(&a)
if err != nil {
log.Printf("[Renewal::RequestUpdate()] Failed to update certificate: %s\n", err)
r.logf("[Renewal::RequestUpdate()] Failed to update certificate: %s", err)
return
}
if len(a) >= 1 {
log.Printf("[Renewal] Unable to update certificate '%d'... Found a newer certificate '%d'\n", c.Id, a[0].DataId)
r.logf("[Renewal] Unable to update certificate '%d'... Found a newer certificate '%d'", c.Id, a[0].DataId)
return
}
@ -212,18 +221,18 @@ func (r *Renewal) fetchDomains(c *certificate2.Certificate) []string {
func (r *Renewal) updateCertificate(c *certificate2.CertificateMetaDomainJoiner) {
domains := r.fetchDomains(&c.Certificate)
log.Printf("[Renewal] Starting renewal service request for '%s' (%d)\n", strings.Join(domains, ", "), c.Id)
r.logf("[Renewal] Starting renewal service request for '%s' (%d)", strings.Join(domains, ", "), c.Id)
c.Renewing = utils.PBool(true)
_, err := r.db.Where("id = ?", c.Id).Update(&c.Certificate)
if err != nil {
log.Println("[Renewal] Failed to update certificate state to (renewing):", err)
r.logf("[Renewal] Failed to update certificate state to (renewing): %s", err)
return
}
client, err := r.setupForRequest(c)
if err != nil {
log.Println("[Renewal] Failed to generate a client for requesting a certificate:", err)
r.logf("[Renewal] Failed to generate a client for requesting a certificate: %s", err)
return
}
@ -233,12 +242,12 @@ func (r *Renewal) updateCertificate(c *certificate2.CertificateMetaDomainJoiner)
}
certificates, err := client.Certificate.Obtain(request)
if err != nil {
log.Printf("[Renewal] Failed to obtain replacement certificate for '%d': %s\n", c.Id, err)
r.logf("[Renewal] Failed to obtain replacement certificate for '%d': %s", c.Id, err)
return
}
newCert := certificate2.CertificateData{
MetaId: c.Id,
MetaId: c.MetaId,
PreviousCert: c.DataId,
CertificateBytes: certificates.Certificate,
KeyBytes: certificates.PrivateKey,
@ -246,32 +255,32 @@ func (r *Renewal) updateCertificate(c *certificate2.CertificateMetaDomainJoiner)
}
err = newCert.UpdateNotAfter()
if err != nil {
log.Printf("[Renewal] Failed to update NotAfter value: %s\n", err)
r.logf("[Renewal] Failed to update NotAfter value: %s", err)
newCert.Ready = utils.PBool(false)
_, _ = r.db.Insert(&newCert)
c.Renewing = utils.PBool(false)
c.RenewFailed = utils.PBool(true)
_, err = r.db.Where("id = ?", c.Id).Update(&c.Certificate)
if err != nil {
log.Println("[Renewal] Failed to update state to (not renewing, renew failed):", err)
r.logf("[Renewal] Failed to update state to (not renewing, renew failed): %s", err)
}
return
}
newCert.PreviousCert = c.Id
_, err = r.db.Insert(&newCert)
if err != nil {
log.Println("[Renewal] Failed to insert new certificate:", err)
r.logf("[Renewal] Failed to insert new certificate: %s", err)
return
}
c.Renewing = utils.PBool(false)
c.RenewFailed = utils.PBool(false)
_, err = r.db.Where("id = ?", c.Id).Update(&c.Certificate)
if err != nil {
log.Println("[Renewal] Failed to update state to (not renewing, not renew failed):", err)
r.logf("[Renewal] Failed to update state to (not renewing, not renew failed): %s", err)
return
}
log.Printf("[Renewal] Successfully generated replacement certificate '%d' for '%d'\n", newCert.DataId, c.Id)
r.logf("[Renewal] Successfully generated replacement certificate '%d' for '%d'", newCert.DataId, c.Id)
return
}
@ -329,6 +338,4 @@ func (r *Renewal) setupForRequest(c *certificate2.CertificateMetaDomainJoiner) (
return client, nil
}
func (r *Renewal) Renew() {
}
func (r *Renewal) Renew() {}