160 lines
No EOL
3.8 KiB
Go
160 lines
No EOL
3.8 KiB
Go
package promote
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"gitea-page/internal/config"
|
|
"github.com/rs/zerolog/log"
|
|
"html/template"
|
|
"os"
|
|
"os/exec"
|
|
"time"
|
|
)
|
|
|
|
type Promote struct {
|
|
Config config.GiteaPagesConfig
|
|
}
|
|
|
|
type PromoterData struct {
|
|
Config config.GiteaPagesConfig
|
|
Repo string
|
|
Owner string
|
|
Domain string
|
|
Path string
|
|
SSL struct{
|
|
Active bool
|
|
Cert string
|
|
Key string
|
|
}
|
|
}
|
|
|
|
func (p Promote) PromoteRepo(name, owner string) {
|
|
log.Debug().Str("name", name).Str("owner", owner).Msg("Promote")
|
|
url := p.getDefaultURL(name, owner)
|
|
log.Debug().Str("url", url).Msg("Promote URL")
|
|
|
|
content := p.getContent(name, owner, url)
|
|
updated := p.updateContent(url, content)
|
|
if updated {
|
|
p.reloadServer()
|
|
}
|
|
log.Debug().Bool("Need to Reload", updated).Msg("File Created")
|
|
|
|
}
|
|
|
|
func (p Promote) reloadServer() {
|
|
reload, err := exec.Command(p.Config.Promoter.Reload.Name, p.Config.Promoter.Reload.Args...).Output()
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("Cant reload Server")
|
|
}
|
|
log.Debug().Str("output", string(reload)).Msg("Reloaded Server")
|
|
}
|
|
|
|
func (p Promote) getSSL(domain, path string) (cert, key string, active bool) {
|
|
if _, err := os.Stat(p.getCertPath(domain, "cer")); err == nil {
|
|
return p.getCertPath(domain, "cer"), p.getCertPath(domain, "key"), true
|
|
}
|
|
return "", "", false
|
|
}
|
|
|
|
func (p Promote) requestSSL(domain, path, name, owner string) {
|
|
log.Debug().Msg("Try to get SSL Zertifikat")
|
|
output, err := exec.Command("/root/.acme.sh/acme.sh", "--issue", "-d", domain, "-w", path).Output()
|
|
if err != nil {
|
|
log.Error().Str("output", string(output)).Err(err).Msg("Cant issue ssl certificat")
|
|
} else {
|
|
log.Info().Str("output", string(output)).Msg("Got SSL zertifikat")
|
|
p.PromoteRepo(name, owner)
|
|
}
|
|
}
|
|
|
|
func (p Promote) updateContent(domain, content string) bool {
|
|
fileName := fmt.Sprintf("%s/%s.conf", p.Config.Promoter.Path, domain)
|
|
log.Debug().Str("filename", fileName).Msg("Promote to File")
|
|
if _, err := os.Stat(fileName); err == nil {
|
|
c, _ := os.ReadFile(fileName)
|
|
if string(c) == content {
|
|
return false
|
|
}
|
|
}
|
|
os.WriteFile(fileName, []byte(content), 0644)
|
|
return true
|
|
}
|
|
|
|
func (p Promote) getContent(name, owner, domain string) string {
|
|
templateContent, err := os.ReadFile(p.Config.Promoter.Template)
|
|
if err != nil {
|
|
log.Panic().Err(err).Msg("Cant get promoter template")
|
|
}
|
|
|
|
var b bytes.Buffer
|
|
templ, err := template.New("").Parse(string(templateContent))
|
|
if err != nil {
|
|
log.Panic().Err(err).Msg("Cant parse Prmoter Template")
|
|
}
|
|
path := fmt.Sprintf("%s/%s/%s", p.Config.RootPath, owner, name)
|
|
promoterData := PromoterData{
|
|
Config: p.Config,
|
|
Repo: name,
|
|
Owner: owner,
|
|
Domain: domain,
|
|
Path: path,
|
|
}
|
|
|
|
cert, key, active := p.getSSL(domain, path)
|
|
promoterData.SSL.Active = active
|
|
promoterData.SSL.Cert = cert
|
|
promoterData.SSL.Key = key
|
|
|
|
err = templ.Execute(&b, promoterData)
|
|
|
|
if err != nil {
|
|
log.Panic().Err(err).Msg("Cant parse Promoter Template")
|
|
}
|
|
|
|
if active == false {
|
|
go func() {
|
|
time.Sleep(10*time.Second)
|
|
p.requestSSL(domain, path, name, owner)
|
|
}()
|
|
}
|
|
|
|
return b.String()
|
|
}
|
|
|
|
func (p Promote) getCertPath(domain, typ string) string {
|
|
var b bytes.Buffer
|
|
templ, err := template.New("").Parse(p.Config.Promoter.CertPath)
|
|
if err != nil {
|
|
log.Panic().Err(err).Msg("Cant parse Cert Path String")
|
|
}
|
|
err = templ.Execute(&b, map[string]interface{}{
|
|
"domain": domain,
|
|
"typ": typ,
|
|
})
|
|
|
|
if err != nil {
|
|
log.Panic().Err(err).Msg("Cant get cert path")
|
|
}
|
|
|
|
return b.String()
|
|
}
|
|
|
|
func (p Promote) getDefaultURL(name, owner string) string {
|
|
log.Debug().Str("domain", p.Config.Domain).Msg("get Default URL")
|
|
var b bytes.Buffer
|
|
templ, err := template.New("").Parse(p.Config.Domain)
|
|
if err != nil {
|
|
log.Panic().Err(err).Msg("Cant parse Config String")
|
|
}
|
|
err = templ.Execute(&b, map[string]interface{}{
|
|
"repro": name,
|
|
"owner": owner,
|
|
})
|
|
|
|
if err != nil {
|
|
log.Panic().Err(err).Msg("Cant get default URL")
|
|
}
|
|
|
|
return b.String()
|
|
} |