mirror of
https://github.com/0xJacky/nginx-ui.git
synced 2025-05-11 02:15:48 +02:00
refactor(cert): introducing new management page
1. User can now view the latest renew logs of the certain certificate. 2. Add manually renew button in certificate modify page for managed certificate (auto cert)
This commit is contained in:
parent
7c47f08a72
commit
ac68fd05c9
36 changed files with 1908 additions and 1286 deletions
|
@ -1,61 +1,13 @@
|
|||
package cert
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/0xJacky/Nginx-UI/internal/logger"
|
||||
"github.com/0xJacky/Nginx-UI/model"
|
||||
"github.com/pkg/errors"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func handleIssueCertLogChan(logChan chan string) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
logger.Error(err)
|
||||
}
|
||||
}()
|
||||
|
||||
for logString := range logChan {
|
||||
logger.Info("Auto Cert", logString)
|
||||
}
|
||||
}
|
||||
|
||||
type AutoCertErrorLog struct {
|
||||
buffer []string
|
||||
cert *model.Cert
|
||||
}
|
||||
|
||||
func (t *AutoCertErrorLog) SetCertModel(cert *model.Cert) {
|
||||
t.cert = cert
|
||||
}
|
||||
|
||||
func (t *AutoCertErrorLog) Push(text string, err error) {
|
||||
t.buffer = append(t.buffer, text+" "+err.Error())
|
||||
logger.Error("AutoCert", text, err)
|
||||
}
|
||||
|
||||
func (t *AutoCertErrorLog) Exit(text string, err error) {
|
||||
t.buffer = append(t.buffer, text+" "+err.Error())
|
||||
logger.Error("AutoCert", text, err)
|
||||
|
||||
if t.cert == nil {
|
||||
return
|
||||
}
|
||||
|
||||
_ = t.cert.Updates(&model.Cert{
|
||||
Log: t.ToString(),
|
||||
})
|
||||
}
|
||||
|
||||
func (t *AutoCertErrorLog) ToString() (content string) {
|
||||
|
||||
for _, v := range t.buffer {
|
||||
content += fmt.Sprintf("[Error] %s\n", v)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func AutoObtain() {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
|
@ -65,64 +17,64 @@ func AutoObtain() {
|
|||
logger.Info("AutoCert Worker Started")
|
||||
autoCertList := model.GetAutoCertList()
|
||||
for _, certModel := range autoCertList {
|
||||
confName := certModel.Filename
|
||||
|
||||
errLog := &AutoCertErrorLog{}
|
||||
errLog.SetCertModel(certModel)
|
||||
|
||||
if len(certModel.Filename) == 0 {
|
||||
errLog.Exit("", errors.New("filename is empty"))
|
||||
continue
|
||||
}
|
||||
|
||||
if len(certModel.Domains) == 0 {
|
||||
errLog.Exit(confName, errors.New("domains list is empty, "+
|
||||
"try to reopen auto-cert for this config:"+confName))
|
||||
continue
|
||||
}
|
||||
|
||||
if certModel.SSLCertificatePath != "" {
|
||||
cert, err := GetCertInfo(certModel.SSLCertificatePath)
|
||||
if err != nil {
|
||||
errLog.Push("get cert info", err)
|
||||
// Get certificate info error, ignore this domain
|
||||
continue
|
||||
}
|
||||
// every week
|
||||
if time.Now().Sub(cert.NotBefore).Hours()/24 < 7 {
|
||||
continue
|
||||
}
|
||||
}
|
||||
// after 1 mo, reissue certificate
|
||||
logChan := make(chan string, 1)
|
||||
errChan := make(chan error, 1)
|
||||
|
||||
// support SAN certification
|
||||
payload := &ConfigPayload{
|
||||
ServerName: certModel.Domains,
|
||||
ChallengeMethod: certModel.ChallengeMethod,
|
||||
DNSCredentialID: certModel.DnsCredentialID,
|
||||
}
|
||||
|
||||
// logChan and errChan should be closed inside IssueCert
|
||||
go IssueCert(payload, logChan, errChan)
|
||||
|
||||
go handleIssueCertLogChan(logChan)
|
||||
|
||||
// block, unless errChan closed
|
||||
for err := range errChan {
|
||||
errLog.Push("issue cert", err)
|
||||
}
|
||||
|
||||
logStr := errLog.ToString()
|
||||
if logStr != "" {
|
||||
// store error log to db
|
||||
_ = certModel.Updates(&model.Cert{
|
||||
Log: errLog.ToString(),
|
||||
})
|
||||
} else {
|
||||
certModel.ClearLog()
|
||||
}
|
||||
certModel := certModel
|
||||
renew(certModel)
|
||||
}
|
||||
logger.Info("AutoCert Worker End")
|
||||
}
|
||||
|
||||
func renew(certModel *model.Cert) {
|
||||
confName := certModel.Filename
|
||||
|
||||
log := &Logger{}
|
||||
log.SetCertModel(certModel)
|
||||
defer log.Exit()
|
||||
|
||||
if len(certModel.Filename) == 0 {
|
||||
log.Error(errors.New("filename is empty"))
|
||||
return
|
||||
}
|
||||
|
||||
if len(certModel.Domains) == 0 {
|
||||
log.Error(errors.New("domains list is empty, " +
|
||||
"try to reopen auto-cert for this config:" + confName))
|
||||
return
|
||||
}
|
||||
|
||||
if certModel.SSLCertificatePath != "" {
|
||||
cert, err := GetCertInfo(certModel.SSLCertificatePath)
|
||||
if err != nil {
|
||||
// Get certificate info error, ignore this certificate
|
||||
log.Error(errors.Wrap(err, "get certificate info error"))
|
||||
return
|
||||
}
|
||||
if time.Now().Sub(cert.NotBefore).Hours()/24 < 7 {
|
||||
// not between 1 week, ignore this certificate
|
||||
return
|
||||
}
|
||||
}
|
||||
// after 1 mo, reissue certificate
|
||||
logChan := make(chan string, 1)
|
||||
errChan := make(chan error, 1)
|
||||
|
||||
// support SAN certification
|
||||
payload := &ConfigPayload{
|
||||
ServerName: certModel.Domains,
|
||||
ChallengeMethod: certModel.ChallengeMethod,
|
||||
DNSCredentialID: certModel.DnsCredentialID,
|
||||
}
|
||||
|
||||
// errChan will be closed inside IssueCert
|
||||
go IssueCert(payload, logChan, errChan)
|
||||
|
||||
go func() {
|
||||
for logString := range logChan {
|
||||
log.Info(strings.TrimSpace(logString))
|
||||
}
|
||||
}()
|
||||
|
||||
// block, unless errChan closed
|
||||
for err := range errChan {
|
||||
log.Error(err)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue