- Added upstream objects

- Renamed host templates to nginx templates
- Generate upstream templates
- Better nginx error reporting when reloading
- Use tparse for golang test reporting
This commit is contained in:
Jamie Curnow
2023-01-04 15:36:56 +10:00
parent b3ae2f4dbb
commit 5e5f0de0e2
82 changed files with 2209 additions and 294 deletions

View File

@ -4,47 +4,97 @@ import (
"fmt"
"npm/internal/config"
"npm/internal/entity/certificate"
"npm/internal/entity/host"
"npm/internal/entity/upstream"
"npm/internal/logger"
"npm/internal/status"
)
// ConfigureHost will attempt to write nginx conf and reload nginx
func ConfigureHost(h host.Model) error {
// nolint: errcheck, gosec
h.Expand([]string{"certificate", "hosttemplate"})
h.Expand([]string{"certificate", "nginxtemplate"})
var certificateTemplate certificate.Template
if h.Certificate != nil {
certificateTemplate = h.Certificate.GetTemplate()
}
data := TemplateData{
ConfDir: fmt.Sprintf("%s/nginx/hosts", config.Configuration.DataFolder),
DataDir: config.Configuration.DataFolder,
Host: h.GetTemplate(),
Certificate: h.Certificate.GetTemplate(),
Certificate: certificateTemplate,
}
filename := fmt.Sprintf("%s/host_%d.conf", data.ConfDir, h.ID)
// Write the config to disk
err := writeTemplate(filename, h.HostTemplate.Template, data)
err := writeTemplate(filename, h.NginxTemplate.Template, data)
if err != nil {
// this configuration failed somehow
h.Status = host.StatusError
h.Status = status.StatusError
h.ErrorMessage = fmt.Sprintf("Template generation failed: %s", err.Error())
logger.Debug(h.ErrorMessage)
return h.Save(true)
}
// nolint: errcheck, gosec
if err := reloadNginx(); err != nil {
if output, err := reloadNginx(); err != nil {
// reloading nginx failed, likely due to this host having a problem
h.Status = host.StatusError
h.ErrorMessage = fmt.Sprintf("Nginx configuation error: %s", err.Error())
h.Status = status.StatusError
h.ErrorMessage = fmt.Sprintf("Nginx configuation error: %s - %s", err.Error(), output)
writeConfigFile(filename, fmt.Sprintf("# %s", h.ErrorMessage))
logger.Debug(h.ErrorMessage)
} else {
// All good
h.Status = host.StatusOK
h.Status = status.StatusOK
h.ErrorMessage = ""
logger.Debug("ConfigureHost OK: %+v", h)
}
return h.Save(true)
}
// ConfigureUpstream will attempt to write nginx conf and reload nginx
func ConfigureUpstream(u upstream.Model) error {
logger.Debug("ConfigureUpstream: %+v)", u)
// nolint: errcheck, gosec
u.Expand([]string{"nginxtemplate"})
data := TemplateData{
ConfDir: fmt.Sprintf("%s/nginx/upstreams", config.Configuration.DataFolder),
DataDir: config.Configuration.DataFolder,
Upstream: u,
}
filename := fmt.Sprintf("%s/upstream_%d.conf", data.ConfDir, u.ID)
// Write the config to disk
err := writeTemplate(filename, u.NginxTemplate.Template, data)
if err != nil {
// this configuration failed somehow
u.Status = status.StatusError
u.ErrorMessage = fmt.Sprintf("Template generation failed: %s", err.Error())
logger.Debug(u.ErrorMessage)
return u.Save(true)
}
// nolint: errcheck, gosec
if output, err := reloadNginx(); err != nil {
// reloading nginx failed, likely due to this host having a problem
u.Status = status.StatusError
u.ErrorMessage = fmt.Sprintf("Nginx configuation error: %s - %s", err.Error(), output)
writeConfigFile(filename, fmt.Sprintf("# %s", u.ErrorMessage))
logger.Debug(u.ErrorMessage)
} else {
// All good
u.Status = status.StatusOK
u.ErrorMessage = ""
logger.Debug("ConfigureUpstream OK: %+v", u)
}
return u.Save(true)
}

View File

@ -7,9 +7,8 @@ import (
"npm/internal/logger"
)
func reloadNginx() error {
_, err := shExec([]string{"-s", "reload"})
return err
func reloadNginx() (string, error) {
return shExec([]string{"-s", "reload"})
}
func getNginxFilePath() (string, error) {
@ -32,7 +31,7 @@ func shExec(args []string) (string, error) {
// nolint: gosec
c := exec.Command(ng, args...)
b, e := c.Output()
b, e := c.CombinedOutput()
if e != nil {
logger.Error("NginxError", fmt.Errorf("Command error: %s -- %v\n%+v", ng, args, e))

View File

@ -6,7 +6,9 @@ import (
"npm/internal/entity/certificate"
"npm/internal/entity/host"
"npm/internal/entity/upstream"
"npm/internal/logger"
"npm/internal/util"
"github.com/aymerick/raymond"
)
@ -17,10 +19,15 @@ type TemplateData struct {
DataDir string
Host host.Template
Certificate certificate.Template
Upstream upstream.Model
}
func generateHostConfig(template string, data TemplateData) (string, error) {
logger.Debug("Rendering Template - Template: %s", template)
logger.Debug("Rendering Template - Data: %+v", data)
return raymond.Render(template, data)
// todo: apply some post processing to this config, stripe trailing whitespace from lines and then remove groups of 2+ \n's so the config looks nicer
}
func writeTemplate(filename, template string, data TemplateData) error {
@ -31,7 +38,7 @@ func writeTemplate(filename, template string, data TemplateData) error {
// Write it. This will also write an error comment if generation failed
// nolint: gosec
writeErr := writeConfigFile(filename, output)
writeErr := writeConfigFile(filename, util.CleanupWhitespace(output))
if err != nil {
return err
}