Skip to content

Commit

Permalink
Merge pull request #298 from nginxinc/prefetch-configmap
Browse files Browse the repository at this point in the history
Prefetch ConfigMap before initial NGINX Config generation
  • Loading branch information
pleshakov authored Jun 27, 2018
2 parents f71e5eb + b303c59 commit 1e67de5
Show file tree
Hide file tree
Showing 6 changed files with 306 additions and 266 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ osx-nginx-plus-ingress
nginx-plus-ingress
nginx-controller/nginx-controller

# Ingress Controller templates
nginx-controller/nginx-plus.ingress.tmpl
nginx-controller/nginx-plus.tmpl

# NGINX Plus license files
*.crt
*.key
Expand Down
255 changes: 3 additions & 252 deletions nginx-controller/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -433,256 +433,7 @@ func (lbc *LoadBalancerController) syncCfgm(task Task) {

if cfgmExists {
cfgm := obj.(*api_v1.ConfigMap)

if serverTokens, exists, err := nginx.GetMapKeyAsBool(cfgm.Data, "server-tokens", cfgm); exists {
if err != nil {
if lbc.nginxPlus {
cfg.ServerTokens = cfgm.Data["server-tokens"]
} else {
glog.Error(err)
}
} else {
cfg.ServerTokens = "off"
if serverTokens {
cfg.ServerTokens = "on"
}
}
}

if lbMethod, exists := cfgm.Data["lb-method"]; exists {
if lbc.nginxPlus {
if parsedMethod, err := nginx.ParseLBMethodForPlus(lbMethod); err != nil {
glog.Errorf("Configmap %s/%s: Invalid value for the lb-method key: got %q: %v", cfgm.GetNamespace(), cfgm.GetName(), lbMethod, err)
} else {
cfg.LBMethod = parsedMethod
}
} else {
if parsedMethod, err := nginx.ParseLBMethod(lbMethod); err != nil {
glog.Errorf("Configmap %s/%s: Invalid value for the lb-method key: got %q: %v", cfgm.GetNamespace(), cfgm.GetName(), lbMethod, err)
} else {
cfg.LBMethod = parsedMethod
}
}
}

if proxyConnectTimeout, exists := cfgm.Data["proxy-connect-timeout"]; exists {
cfg.ProxyConnectTimeout = proxyConnectTimeout
}
if proxyReadTimeout, exists := cfgm.Data["proxy-read-timeout"]; exists {
cfg.ProxyReadTimeout = proxyReadTimeout
}
if proxyHideHeaders, exists, err := nginx.GetMapKeyAsStringSlice(cfgm.Data, "proxy-hide-headers", cfgm, ","); exists {
if err != nil {
glog.Error(err)
} else {
cfg.ProxyHideHeaders = proxyHideHeaders
}
}
if proxyPassHeaders, exists, err := nginx.GetMapKeyAsStringSlice(cfgm.Data, "proxy-pass-headers", cfgm, ","); exists {
if err != nil {
glog.Error(err)
} else {
cfg.ProxyPassHeaders = proxyPassHeaders
}
}
if clientMaxBodySize, exists := cfgm.Data["client-max-body-size"]; exists {
cfg.ClientMaxBodySize = clientMaxBodySize
}
if serverNamesHashBucketSize, exists := cfgm.Data["server-names-hash-bucket-size"]; exists {
cfg.MainServerNamesHashBucketSize = serverNamesHashBucketSize
}
if serverNamesHashMaxSize, exists := cfgm.Data["server-names-hash-max-size"]; exists {
cfg.MainServerNamesHashMaxSize = serverNamesHashMaxSize
}
if HTTP2, exists, err := nginx.GetMapKeyAsBool(cfgm.Data, "http2", cfgm); exists {
if err != nil {
glog.Error(err)
} else {
cfg.HTTP2 = HTTP2
}
}
if redirectToHTTPS, exists, err := nginx.GetMapKeyAsBool(cfgm.Data, "redirect-to-https", cfgm); exists {
if err != nil {
glog.Error(err)
} else {
cfg.RedirectToHTTPS = redirectToHTTPS
}
}
if sslRedirect, exists, err := nginx.GetMapKeyAsBool(cfgm.Data, "ssl-redirect", cfgm); exists {
if err != nil {
glog.Error(err)
} else {
cfg.SSLRedirect = sslRedirect
}
}

// HSTS block
if hsts, exists, err := nginx.GetMapKeyAsBool(cfgm.Data, "hsts", cfgm); exists {
if err != nil {
glog.Error(err)
} else {
parsingErrors := false

hstsMaxAge, existsMA, err := nginx.GetMapKeyAsInt(cfgm.Data, "hsts-max-age", cfgm)
if existsMA && err != nil {
glog.Error(err)
parsingErrors = true
}
hstsIncludeSubdomains, existsIS, err := nginx.GetMapKeyAsBool(cfgm.Data, "hsts-include-subdomains", cfgm)
if existsIS && err != nil {
glog.Error(err)
parsingErrors = true
}

if parsingErrors {
glog.Errorf("Configmap %s/%s: There are configuration issues with hsts annotations, skipping options for all hsts settings", cfgm.GetNamespace(), cfgm.GetName())
} else {
cfg.HSTS = hsts
if existsMA {
cfg.HSTSMaxAge = hstsMaxAge
}
if existsIS {
cfg.HSTSIncludeSubdomains = hstsIncludeSubdomains
}
}
}
}

if proxyProtocol, exists, err := nginx.GetMapKeyAsBool(cfgm.Data, "proxy-protocol", cfgm); exists {
if err != nil {
glog.Error(err)
} else {
cfg.ProxyProtocol = proxyProtocol
}
}

// ngx_http_realip_module
if realIPHeader, exists := cfgm.Data["real-ip-header"]; exists {
cfg.RealIPHeader = realIPHeader
}
if setRealIPFrom, exists, err := nginx.GetMapKeyAsStringSlice(cfgm.Data, "set-real-ip-from", cfgm, ","); exists {
if err != nil {
glog.Error(err)
} else {
cfg.SetRealIPFrom = setRealIPFrom
}
}
if realIPRecursive, exists, err := nginx.GetMapKeyAsBool(cfgm.Data, "real-ip-recursive", cfgm); exists {
if err != nil {
glog.Error(err)
} else {
cfg.RealIPRecursive = realIPRecursive
}
}

// SSL block
if sslProtocols, exists := cfgm.Data["ssl-protocols"]; exists {
cfg.MainServerSSLProtocols = sslProtocols
}
if sslPreferServerCiphers, exists, err := nginx.GetMapKeyAsBool(cfgm.Data, "ssl-prefer-server-ciphers", cfgm); exists {
if err != nil {
glog.Error(err)
} else {
cfg.MainServerSSLPreferServerCiphers = sslPreferServerCiphers
}
}
if sslCiphers, exists := cfgm.Data["ssl-ciphers"]; exists {
cfg.MainServerSSLCiphers = strings.Trim(sslCiphers, "\n")
}
if sslDHParamFile, exists := cfgm.Data["ssl-dhparam-file"]; exists {
sslDHParamFile = strings.Trim(sslDHParamFile, "\n")
fileName, err := lbc.cnf.AddOrUpdateDHParam(sslDHParamFile)
if err != nil {
glog.Errorf("Configmap %s/%s: Could not update dhparams: %v", cfgm.GetNamespace(), cfgm.GetName(), err)
} else {
cfg.MainServerSSLDHParam = fileName
}
}

if logFormat, exists := cfgm.Data["log-format"]; exists {
cfg.MainLogFormat = logFormat
}
if proxyBuffering, exists, err := nginx.GetMapKeyAsBool(cfgm.Data, "proxy-buffering", cfgm); exists {
if err != nil {
glog.Error(err)
} else {
cfg.ProxyBuffering = proxyBuffering
}
}
if proxyBuffers, exists := cfgm.Data["proxy-buffers"]; exists {
cfg.ProxyBuffers = proxyBuffers
}
if proxyBufferSize, exists := cfgm.Data["proxy-buffer-size"]; exists {
cfg.ProxyBufferSize = proxyBufferSize
}
if proxyMaxTempFileSize, exists := cfgm.Data["proxy-max-temp-file-size"]; exists {
cfg.ProxyMaxTempFileSize = proxyMaxTempFileSize
}

if mainMainSnippets, exists, err := nginx.GetMapKeyAsStringSlice(cfgm.Data, "main-snippets", cfgm, "\n"); exists {
if err != nil {
glog.Error(err)
} else {
cfg.MainMainSnippets = mainMainSnippets
}
}
if mainHTTPSnippets, exists, err := nginx.GetMapKeyAsStringSlice(cfgm.Data, "http-snippets", cfgm, "\n"); exists {
if err != nil {
glog.Error(err)
} else {
cfg.MainHTTPSnippets = mainHTTPSnippets
}
}
if locationSnippets, exists, err := nginx.GetMapKeyAsStringSlice(cfgm.Data, "location-snippets", cfgm, "\n"); exists {
if err != nil {
glog.Error(err)
} else {
cfg.LocationSnippets = locationSnippets
}
}
if serverSnippets, exists, err := nginx.GetMapKeyAsStringSlice(cfgm.Data, "server-snippets", cfgm, "\n"); exists {
if err != nil {
glog.Error(err)
} else {
cfg.ServerSnippets = serverSnippets
}
}
if _, exists, err := nginx.GetMapKeyAsInt(cfgm.Data, "worker-processes", cfgm); exists {
if err != nil && cfgm.Data["worker-processes"] != "auto" {
glog.Errorf("Configmap %s/%s: Invalid value for worker-processes key: must be an integer or the string 'auto', got %q", cfgm.GetNamespace(), cfgm.GetName(), cfgm.Data["worker-processes"])
} else {
cfg.MainWorkerProcesses = cfgm.Data["worker-processes"]
}
}
if workerCPUAffinity, exists := cfgm.Data["worker-cpu-affinity"]; exists {
cfg.MainWorkerCPUAffinity = workerCPUAffinity
}
if workerShutdownTimeout, exists := cfgm.Data["worker-shutdown-timeout"]; exists {
cfg.MainWorkerShutdownTimeout = workerShutdownTimeout
}
if workerConnections, exists := cfgm.Data["worker-connections"]; exists {
cfg.MainWorkerConnections = workerConnections
}
if workerRlimitNofile, exists := cfgm.Data["worker-rlimit-nofile"]; exists {
cfg.MainWorkerRlimitNofile = workerRlimitNofile
}
if keepalive, exists, err := nginx.GetMapKeyAsInt(cfgm.Data, "keepalive", cfgm); exists {
if err != nil {
glog.Error(err)
} else {
cfg.Keepalive = keepalive
}
}
if maxFails, exists, err := nginx.GetMapKeyAsInt(cfgm.Data, "max-fails", cfgm); exists {
if err != nil {
glog.Error(err)
} else {
cfg.MaxFails = maxFails
}
}
if failTimeout, exists := cfgm.Data["fail-timeout"]; exists {
cfg.FailTimeout = failTimeout
}
cfg = nginx.ParseConfigMap(cfgm, lbc.nginxPlus)
}

mergeableIngresses := make(map[string]*nginx.MergeableIngresses)
Expand Down Expand Up @@ -1277,9 +1028,9 @@ func (lbc *LoadBalancerController) isNginxIngress(ing *extensions.Ingress) bool
return class == lbc.ingressClass
}
return class == lbc.ingressClass || class == ""
} else {
return !lbc.useIngressClassOnly
}
return !lbc.useIngressClassOnly

}

// isHealthCheckEnabled checks if health checks are enabled so we can only query pods if enabled.
Expand Down
26 changes: 24 additions & 2 deletions nginx-controller/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,32 @@ func main() {
}
}

cfg := nginx.NewDefaultConfig()
if *nginxConfigMaps != "" {
ns, name, err := controller.ParseNamespaceName(*nginxConfigMaps)
if err != nil {
glog.Fatalf("Error parsing the nginx-configmaps argument: %v", err)
}
cfm, err := kubeClient.CoreV1().ConfigMaps(ns).Get(name, meta_v1.GetOptions{})
if err != nil {
glog.Fatalf("Error when getting %v: %v", *nginxConfigMaps, err)
}
cfg = nginx.ParseConfigMap(cfm, *nginxPlus)
if cfg.MainServerSSLDHParamFileContent != nil {
fileName, err := ngxc.AddOrUpdateDHParam(*cfg.MainServerSSLDHParamFileContent)
if err != nil {
glog.Fatalf("Configmap %s/%s: Could not update dhparams: %v", ns, name, err)
} else {
cfg.MainServerSSLDHParam = fileName
}
}
}
ngxConfig := nginx.GenerateNginxMainConfig(cfg)
ngxc.UpdateMainConfigFile(ngxConfig)

nginxDone := make(chan error, 1)
ngxc.Start(nginxDone)

nginxConfig := nginx.NewDefaultConfig()
var nginxAPI *plus.NginxAPIController
if *nginxPlus {
time.Sleep(500 * time.Millisecond)
Expand All @@ -142,8 +164,8 @@ func main() {
glog.Fatalf("Failed to create NginxAPIController: %v", err)
}
}
cnf := nginx.NewConfigurator(ngxc, nginxConfig, nginxAPI)

cnf := nginx.NewConfigurator(ngxc, cfg, nginxAPI)
lbc := controller.NewLoadBalancerController(kubeClient, 30*time.Second, *watchNamespace, cnf, *nginxConfigMaps, *defaultServerSecret, *nginxPlus, *ingressClass, *useIngressClassOnly)
go handleTermination(lbc, ngxc, nginxDone)
lbc.Run()
Expand Down
Loading

0 comments on commit 1e67de5

Please sign in to comment.