mirror of
https://github.com/jc21/nginx-proxy-manager.git
synced 2024-08-30 18:22:48 +00:00
Nginx config files with suffixes for deleted/disabled/errors
This commit is contained in:
parent
17a108f75f
commit
6efa4e2beb
@ -150,11 +150,6 @@ INSERT INTO `nginx_template` (
|
|||||||
{{/each}}
|
{{/each}}
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
|
|
||||||
{{#if Host.IsDisabled}}
|
|
||||||
# This Proxy Host is disabled and will not generate functional config
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{#unless Host.IsDisabled}}
|
|
||||||
server {
|
server {
|
||||||
set $forward_scheme {{Host.ForwardScheme}} http; # todo
|
set $forward_scheme {{Host.ForwardScheme}} http; # todo
|
||||||
set $server ""{{Host.ForwardHost}}""; # todo
|
set $server ""{{Host.ForwardHost}}""; # todo
|
||||||
@ -270,7 +265,6 @@ server {
|
|||||||
# Legacy Custom Configuration
|
# Legacy Custom Configuration
|
||||||
include /data/nginx/custom/server_proxy[.]conf;
|
include /data/nginx/custom/server_proxy[.]conf;
|
||||||
}
|
}
|
||||||
{{/unless}}
|
|
||||||
"
|
"
|
||||||
), (
|
), (
|
||||||
strftime('%s', 'now'),
|
strftime('%s', 'now'),
|
||||||
@ -303,8 +297,6 @@ server {
|
|||||||
# Upstream {{Upstream.ID}}: {{Upstream.Name}}
|
# Upstream {{Upstream.ID}}: {{Upstream.Name}}
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
|
|
||||||
{{#unless Upstream.IsDeleted~}}
|
|
||||||
|
|
||||||
upstream npm_upstream_{{Upstream.ID}} {
|
upstream npm_upstream_{{Upstream.ID}} {
|
||||||
|
|
||||||
{{#if Upstream.IPHash~}}
|
{{#if Upstream.IPHash~}}
|
||||||
@ -339,8 +331,6 @@ upstream npm_upstream_{{Upstream.ID}} {
|
|||||||
{{/unless}}
|
{{/unless}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
}
|
}
|
||||||
|
|
||||||
{{~/unless~}}
|
|
||||||
"
|
"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -152,6 +152,7 @@ func DeleteHost() func(http.ResponseWriter, *http.Request) {
|
|||||||
h.ResultErrorJSON(w, r, http.StatusNotFound, "Not found", nil)
|
h.ResultErrorJSON(w, r, http.StatusNotFound, "Not found", nil)
|
||||||
case nil:
|
case nil:
|
||||||
h.ResultResponseJSON(w, r, http.StatusOK, item.Delete())
|
h.ResultResponseJSON(w, r, http.StatusOK, item.Delete())
|
||||||
|
configureHost(item)
|
||||||
default:
|
default:
|
||||||
h.ResultErrorJSON(w, r, http.StatusBadRequest, err.Error(), nil)
|
h.ResultErrorJSON(w, r, http.StatusBadRequest, err.Error(), nil)
|
||||||
}
|
}
|
||||||
|
@ -110,6 +110,7 @@ func DeleteUpstream() func(http.ResponseWriter, *http.Request) {
|
|||||||
h.ResultErrorJSON(w, r, http.StatusNotFound, "Not found", nil)
|
h.ResultErrorJSON(w, r, http.StatusNotFound, "Not found", nil)
|
||||||
case nil:
|
case nil:
|
||||||
h.ResultResponseJSON(w, r, http.StatusOK, item.Delete())
|
h.ResultResponseJSON(w, r, http.StatusOK, item.Delete())
|
||||||
|
configureUpstream(item)
|
||||||
default:
|
default:
|
||||||
h.ResultErrorJSON(w, r, http.StatusBadRequest, err.Error(), nil)
|
h.ResultErrorJSON(w, r, http.StatusBadRequest, err.Error(), nil)
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package nginx
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
"npm/internal/config"
|
"npm/internal/config"
|
||||||
"npm/internal/entity/certificate"
|
"npm/internal/entity/certificate"
|
||||||
@ -11,7 +12,15 @@ import (
|
|||||||
"npm/internal/status"
|
"npm/internal/status"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
DeletedSuffix = ".deleted"
|
||||||
|
DisabledSuffix = ".disabled"
|
||||||
|
ErrorSuffix = ".error"
|
||||||
|
)
|
||||||
|
|
||||||
// ConfigureHost will attempt to write nginx conf and reload nginx
|
// ConfigureHost will attempt to write nginx conf and reload nginx
|
||||||
|
// When a host is disabled or deleted, it will name the file with a suffix
|
||||||
|
// that won't be used by nginx.
|
||||||
func ConfigureHost(h host.Model) error {
|
func ConfigureHost(h host.Model) error {
|
||||||
// nolint: errcheck, gosec
|
// nolint: errcheck, gosec
|
||||||
h.Expand([]string{"certificate", "nginxtemplate", "upstream"})
|
h.Expand([]string{"certificate", "nginxtemplate", "upstream"})
|
||||||
@ -33,10 +42,16 @@ func ConfigureHost(h host.Model) error {
|
|||||||
Upstream: h.Upstream,
|
Upstream: h.Upstream,
|
||||||
}
|
}
|
||||||
|
|
||||||
filename := fmt.Sprintf("%s/host_%d.conf", data.ConfDir, h.ID)
|
removeHostFiles(h)
|
||||||
|
filename := getHostFilename(h, "")
|
||||||
|
if h.IsDeleted {
|
||||||
|
filename = getHostFilename(h, DeletedSuffix)
|
||||||
|
} else if h.IsDisabled {
|
||||||
|
filename = getHostFilename(h, DisabledSuffix)
|
||||||
|
}
|
||||||
|
|
||||||
// Write the config to disk
|
// Write the config to disk
|
||||||
err := writeTemplate(filename, h.NginxTemplate.Template, data)
|
err := writeTemplate(filename, h.NginxTemplate.Template, data, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// this configuration failed somehow
|
// this configuration failed somehow
|
||||||
h.Status = status.StatusError
|
h.Status = status.StatusError
|
||||||
@ -45,12 +60,23 @@ func ConfigureHost(h host.Model) error {
|
|||||||
return h.Save(true)
|
return h.Save(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// nolint: errcheck, gosec
|
// Reload Nginx and check for errors
|
||||||
if output, err := reloadNginx(); err != nil {
|
if output, err := reloadNginx(); err != nil {
|
||||||
// reloading nginx failed, likely due to this host having a problem
|
// reloading nginx failed, likely due to this host having a problem
|
||||||
h.Status = status.StatusError
|
h.Status = status.StatusError
|
||||||
h.ErrorMessage = fmt.Sprintf("Nginx configuation error: %s - %s", err.Error(), output)
|
h.ErrorMessage = fmt.Sprintf("Nginx configuation error: %s - %s", err.Error(), output)
|
||||||
writeConfigFile(filename, fmt.Sprintf("# %s", h.ErrorMessage))
|
|
||||||
|
// Write the .error file, if this isn't a deleted or disabled host
|
||||||
|
// as the reload will only fail because of this host, if it's enabled
|
||||||
|
if !h.IsDeleted && !h.IsDisabled {
|
||||||
|
filename = getHostFilename(h, ErrorSuffix)
|
||||||
|
// Clear existing file(s) again
|
||||||
|
removeHostFiles(h)
|
||||||
|
// Write the template again, but with an error message at the end of the file
|
||||||
|
// nolint: errcheck, gosec
|
||||||
|
writeTemplate(filename, h.NginxTemplate.Template, data, h.ErrorMessage)
|
||||||
|
}
|
||||||
|
|
||||||
logger.Debug(h.ErrorMessage)
|
logger.Debug(h.ErrorMessage)
|
||||||
} else {
|
} else {
|
||||||
// All good
|
// All good
|
||||||
@ -75,10 +101,14 @@ func ConfigureUpstream(u upstream.Model) error {
|
|||||||
Upstream: u,
|
Upstream: u,
|
||||||
}
|
}
|
||||||
|
|
||||||
filename := fmt.Sprintf("%s/upstream_%d.conf", data.ConfDir, u.ID)
|
removeUpstreamFiles(u)
|
||||||
|
filename := getUpstreamFilename(u, "")
|
||||||
|
if u.IsDeleted {
|
||||||
|
filename = getUpstreamFilename(u, DeletedSuffix)
|
||||||
|
}
|
||||||
|
|
||||||
// Write the config to disk
|
// Write the config to disk
|
||||||
err := writeTemplate(filename, u.NginxTemplate.Template, data)
|
err := writeTemplate(filename, u.NginxTemplate.Template, data, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// this configuration failed somehow
|
// this configuration failed somehow
|
||||||
u.Status = status.StatusError
|
u.Status = status.StatusError
|
||||||
@ -92,7 +122,18 @@ func ConfigureUpstream(u upstream.Model) error {
|
|||||||
// reloading nginx failed, likely due to this host having a problem
|
// reloading nginx failed, likely due to this host having a problem
|
||||||
u.Status = status.StatusError
|
u.Status = status.StatusError
|
||||||
u.ErrorMessage = fmt.Sprintf("Nginx configuation error: %s - %s", err.Error(), output)
|
u.ErrorMessage = fmt.Sprintf("Nginx configuation error: %s - %s", err.Error(), output)
|
||||||
writeConfigFile(filename, fmt.Sprintf("# %s", u.ErrorMessage))
|
|
||||||
|
// Write the .error file, if this isn't a deleted upstream
|
||||||
|
// as the reload will only fail because of this upstream
|
||||||
|
if !u.IsDeleted {
|
||||||
|
filename = getUpstreamFilename(u, ErrorSuffix)
|
||||||
|
// Clear existing file(s) again
|
||||||
|
removeUpstreamFiles(u)
|
||||||
|
// Write the template again, but with an error message at the end of the file
|
||||||
|
// nolint: errcheck, gosec
|
||||||
|
writeTemplate(filename, u.NginxTemplate.Template, data, u.ErrorMessage)
|
||||||
|
}
|
||||||
|
|
||||||
logger.Debug(u.ErrorMessage)
|
logger.Debug(u.ErrorMessage)
|
||||||
} else {
|
} else {
|
||||||
// All good
|
// All good
|
||||||
@ -103,3 +144,39 @@ func ConfigureUpstream(u upstream.Model) error {
|
|||||||
|
|
||||||
return u.Save(true)
|
return u.Save(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getHostFilename(h host.Model, append string) string {
|
||||||
|
confDir := fmt.Sprintf("%s/nginx/hosts", config.Configuration.DataFolder)
|
||||||
|
return fmt.Sprintf("%s/host_%d.conf%s", confDir, h.ID, append)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getUpstreamFilename(u upstream.Model, append string) string {
|
||||||
|
confDir := fmt.Sprintf("%s/nginx/upstreams", config.Configuration.DataFolder)
|
||||||
|
return fmt.Sprintf("%s/upstream_%d.conf%s", confDir, u.ID, append)
|
||||||
|
}
|
||||||
|
|
||||||
|
func removeHostFiles(h host.Model) {
|
||||||
|
removeFiles([]string{
|
||||||
|
getHostFilename(h, ""),
|
||||||
|
getHostFilename(h, DeletedSuffix),
|
||||||
|
getHostFilename(h, DisabledSuffix),
|
||||||
|
getHostFilename(h, ErrorSuffix),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func removeUpstreamFiles(u upstream.Model) {
|
||||||
|
removeFiles([]string{
|
||||||
|
getUpstreamFilename(u, ""),
|
||||||
|
getUpstreamFilename(u, DeletedSuffix),
|
||||||
|
getUpstreamFilename(u, ErrorSuffix),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func removeFiles(files []string) {
|
||||||
|
for _, file := range files {
|
||||||
|
if _, err := os.Stat(file); err == nil {
|
||||||
|
// nolint: errcheck, gosec
|
||||||
|
os.Remove(file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -34,15 +34,22 @@ func renderTemplate(template string, data TemplateData) (string, error) {
|
|||||||
return raymond.Render(template, data)
|
return raymond.Render(template, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeTemplate(filename, template string, data TemplateData) error {
|
func writeTemplate(filename, template string, data TemplateData, errorInfo string) error {
|
||||||
output, err := renderTemplate(template, data)
|
output, err := renderTemplate(template, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
output = fmt.Sprintf("# Template Error: %s", err.Error())
|
errorInfo = err.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
output = util.CleanupWhitespace(output)
|
||||||
|
|
||||||
|
// Write some given error information to the end
|
||||||
|
if errorInfo != "" {
|
||||||
|
output = fmt.Sprintf("%s\n\n# =========================\n# ERROR:\n# %s\n# ========================\n", output, errorInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write it. This will also write an error comment if generation failed
|
// Write it. This will also write an error comment if generation failed
|
||||||
// nolint: gosec
|
// nolint: gosec
|
||||||
writeErr := writeConfigFile(filename, util.CleanupWhitespace(output))
|
writeErr := writeConfigFile(filename, output)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user