Avoid replacing nginx.conf file if the new configuration is invalid
This commit is contained in:
parent
e74b8039a5
commit
db3388e777
2 changed files with 38 additions and 7 deletions
|
@ -18,6 +18,7 @@ package nginx
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
@ -63,7 +64,7 @@ func (ngx *Manager) CheckAndReload(cfg config.Configuration, ingressCfg ingress.
|
|||
ngx.reloadLock.Lock()
|
||||
defer ngx.reloadLock.Unlock()
|
||||
|
||||
newCfg, err := ngx.template.Write(cfg, ingressCfg)
|
||||
newCfg, err := ngx.template.Write(cfg, ingressCfg, ngx.testTemplate)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write new nginx configuration. Avoiding reload: %v", err)
|
||||
}
|
||||
|
@ -118,3 +119,19 @@ func (ngx Manager) Check(_ *http.Request) error {
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
// testTemplate checks if the NGINX configuration inside the byte array is valid
|
||||
// running the command "nginx -t" using a temporal file.
|
||||
func (ngx Manager) testTemplate(cfg []byte) error {
|
||||
tmpfile, err := ioutil.TempFile("", "nginx-cfg")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tmpfile.Close()
|
||||
defer os.Remove(tmpfile.Name())
|
||||
ioutil.WriteFile(tmpfile.Name(), cfg, 0644)
|
||||
if err := ngx.shellOut(fmt.Sprintf("nginx -t -c %v", tmpfile.Name())); err != nil {
|
||||
return fmt.Errorf("invalid nginx configuration: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -91,7 +91,10 @@ func (t *Template) Close() {
|
|||
|
||||
// Write populates a buffer using a template with NGINX configuration
|
||||
// and the servers and upstreams created by Ingress rules
|
||||
func (t *Template) Write(cfg config.Configuration, ingressCfg ingress.Configuration) ([]byte, error) {
|
||||
func (t *Template) Write(
|
||||
cfg config.Configuration,
|
||||
ingressCfg ingress.Configuration,
|
||||
isValidTemplate func([]byte) error) ([]byte, error) {
|
||||
var longestName int
|
||||
var serverNames int
|
||||
for _, srv := range ingressCfg.Servers {
|
||||
|
@ -109,12 +112,14 @@ func (t *Template) Write(cfg config.Configuration, ingressCfg ingress.Configurat
|
|||
// https://trac.nginx.org/nginx/ticket/631
|
||||
nameHashBucketSize := nextPowerOf2(longestName)
|
||||
if nameHashBucketSize > cfg.ServerNameHashBucketSize {
|
||||
glog.V(3).Infof("adjusting ServerNameHashBucketSize variable from %v to %v", cfg.ServerNameHashBucketSize, nameHashBucketSize)
|
||||
glog.V(3).Infof("adjusting ServerNameHashBucketSize variable from %v to %v",
|
||||
cfg.ServerNameHashBucketSize, nameHashBucketSize)
|
||||
cfg.ServerNameHashBucketSize = nameHashBucketSize
|
||||
}
|
||||
serverNameHashMaxSize := nextPowerOf2(serverNames)
|
||||
if serverNameHashMaxSize > cfg.ServerNameHashMaxSize {
|
||||
glog.V(3).Infof("adjusting ServerNameHashMaxSize variable from %v to %v", cfg.ServerNameHashMaxSize, serverNameHashMaxSize)
|
||||
glog.V(3).Infof("adjusting ServerNameHashMaxSize variable from %v to %v",
|
||||
cfg.ServerNameHashMaxSize, serverNameHashMaxSize)
|
||||
cfg.ServerNameHashMaxSize = serverNameHashMaxSize
|
||||
}
|
||||
|
||||
|
@ -141,9 +146,15 @@ func (t *Template) Write(cfg config.Configuration, ingressCfg ingress.Configurat
|
|||
err := t.tmpl.Execute(buffer, conf)
|
||||
if err != nil {
|
||||
glog.V(3).Infof("%v", string(buffer.Bytes()))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buffer.Bytes(), err
|
||||
err = isValidTemplate(buffer.Bytes())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buffer.Bytes(), nil
|
||||
}
|
||||
|
||||
func fixKeyNames(data map[string]interface{}) map[string]interface{} {
|
||||
|
@ -258,13 +269,16 @@ func buildRateLimitZones(input interface{}) []string {
|
|||
|
||||
if loc.RateLimit.Connections.Limit > 0 {
|
||||
zone := fmt.Sprintf("limit_conn_zone $binary_remote_addr zone=%v:%vm;",
|
||||
loc.RateLimit.Connections.Name, loc.RateLimit.Connections.SharedSize)
|
||||
loc.RateLimit.Connections.Name,
|
||||
loc.RateLimit.Connections.SharedSize)
|
||||
zones = append(zones, zone)
|
||||
}
|
||||
|
||||
if loc.RateLimit.RPS.Limit > 0 {
|
||||
zone := fmt.Sprintf("limit_conn_zone $binary_remote_addr zone=%v:%vm rate=%vr/s;",
|
||||
loc.RateLimit.Connections.Name, loc.RateLimit.Connections.SharedSize, loc.RateLimit.Connections.Limit)
|
||||
loc.RateLimit.Connections.Name,
|
||||
loc.RateLimit.Connections.SharedSize,
|
||||
loc.RateLimit.Connections.Limit)
|
||||
zones = append(zones, zone)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue