Merge pull request #92 from aledbf/custom-timeouts

Refactoring of nginx configuration deserialization
This commit is contained in:
Manuel Alejandro de Brito Fontes 2017-01-02 11:35:14 -03:00 committed by GitHub
commit 6af7684161
4 changed files with 78 additions and 129 deletions

View file

@ -76,145 +76,145 @@ var (
// Configuration represents the content of nginx.conf file
type Configuration struct {
defaults.Backend
defaults.Backend `json:",squash"`
// http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size
// Sets the maximum allowed size of the client request body
BodySize string `structs:"body-size,omitempty"`
BodySize string `json:"body-size,omitempty"`
// EnableDynamicTLSRecords enables dynamic TLS record sizes
// https://blog.cloudflare.com/optimizing-tls-over-tcp-to-reduce-latency
// By default this is enabled
EnableDynamicTLSRecords bool `structs:"enable-dynamic-tls-records"`
EnableDynamicTLSRecords bool `json:"enable-dynamic-tls-records"`
// EnableSPDY enables spdy and use ALPN and NPN to advertise the availability of the two protocols
// https://blog.cloudflare.com/open-sourcing-our-nginx-http-2-spdy-code
// By default this is enabled
EnableSPDY bool `structs:"enable-spdy"`
EnableSPDY bool `json:"enable-spdy"`
// EnableStickySessions enabled sticky sessions using cookies
// https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng
// By default this is disabled
EnableStickySessions bool `structs:"enable-sticky-sessions,omitempty"`
EnableStickySessions bool `json:"enable-sticky-sessions,omitempty"`
// EnableVtsStatus allows the replacement of the default status page with a third party module named
// nginx-module-vts - https://github.com/vozlt/nginx-module-vts
// By default this is disabled
EnableVtsStatus bool `structs:"enable-vts-status,omitempty"`
EnableVtsStatus bool `json:"enable-vts-status,omitempty"`
VtsStatusZoneSize string `structs:"vts-status-zone-size,omitempty"`
VtsStatusZoneSize string `json:"vts-status-zone-size,omitempty"`
// RetryNonIdempotent since 1.9.13 NGINX will not retry non-idempotent requests (POST, LOCK, PATCH)
// in case of an error. The previous behavior can be restored using the value true
RetryNonIdempotent bool `structs:"retry-non-idempotent"`
RetryNonIdempotent bool `json:"retry-non-idempotent"`
// http://nginx.org/en/docs/ngx_core_module.html#error_log
// Configures logging level [debug | info | notice | warn | error | crit | alert | emerg]
// Log levels above are listed in the order of increasing severity
ErrorLogLevel string `structs:"error-log-level,omitempty"`
ErrorLogLevel string `json:"error-log-level,omitempty"`
// Enables or disables the header HSTS in servers running SSL
HSTS bool `structs:"hsts,omitempty"`
HSTS bool `json:"hsts,omitempty"`
// Enables or disables the use of HSTS in all the subdomains of the servername
// Default: true
HSTSIncludeSubdomains bool `structs:"hsts-include-subdomains,omitempty"`
HSTSIncludeSubdomains bool `json:"hsts-include-subdomains,omitempty"`
// HTTP Strict Transport Security (often abbreviated as HSTS) is a security feature (HTTP header)
// that tell browsers that it should only be communicated with using HTTPS, instead of using HTTP.
// https://developer.mozilla.org/en-US/docs/Web/Security/HTTP_strict_transport_security
// max-age is the time, in seconds, that the browser should remember that this site is only to be
// accessed using HTTPS.
HSTSMaxAge string `structs:"hsts-max-age,omitempty"`
HSTSMaxAge string `json:"hsts-max-age,omitempty"`
// Time during which a keep-alive client connection will stay open on the server side.
// The zero value disables keep-alive client connections
// http://nginx.org/en/docs/http/ngx_http_core_module.html#keepalive_timeout
KeepAlive int `structs:"keep-alive,omitempty"`
KeepAlive int `json:"keep-alive,omitempty"`
// Maximum number of simultaneous connections that can be opened by each worker process
// http://nginx.org/en/docs/ngx_core_module.html#worker_connections
MaxWorkerConnections int `structs:"max-worker-connections,omitempty"`
MaxWorkerConnections int `json:"max-worker-connections,omitempty"`
// Sets the bucket size for the map variables hash tables.
// Default value depends on the processors cache line size.
// http://nginx.org/en/docs/http/ngx_http_map_module.html#map_hash_bucket_size
MapHashBucketSize int `structs:"map-hash-bucket-size,omitempty"`
MapHashBucketSize int `json:"map-hash-bucket-size,omitempty"`
// If UseProxyProtocol is enabled ProxyRealIPCIDR defines the default the IP/network address
// of your external load balancer
ProxyRealIPCIDR string `structs:"proxy-real-ip-cidr,omitempty"`
ProxyRealIPCIDR string `json:"proxy-real-ip-cidr,omitempty"`
// Maximum size of the server names hash tables used in server names, map directives values,
// MIME types, names of request header strings, etcd.
// http://nginx.org/en/docs/hash.html
// http://nginx.org/en/docs/http/ngx_http_core_module.html#server_names_hash_max_size
ServerNameHashMaxSize int `structs:"server-name-hash-max-size,omitempty"`
ServerNameHashMaxSize int `json:"server-name-hash-max-size,omitempty"`
// Size of the bucket for the server names hash tables
// http://nginx.org/en/docs/hash.html
// http://nginx.org/en/docs/http/ngx_http_core_module.html#server_names_hash_bucket_size
ServerNameHashBucketSize int `structs:"server-name-hash-bucket-size,omitempty"`
ServerNameHashBucketSize int `json:"server-name-hash-bucket-size,omitempty"`
// Enabled ciphers list to enabled. The ciphers are specified in the format understood by
// the OpenSSL library
// http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_ciphers
SSLCiphers string `structs:"ssl-ciphers,omitempty"`
SSLCiphers string `json:"ssl-ciphers,omitempty"`
// Base64 string that contains Diffie-Hellman key to help with "Perfect Forward Secrecy"
// https://www.openssl.org/docs/manmaster/apps/dhparam.html
// https://wiki.mozilla.org/Security/Server_Side_TLS#DHE_handshake_and_dhparam
// http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_dhparam
SSLDHParam string `structs:"ssl-dh-param,omitempty"`
SSLDHParam string `json:"ssl-dh-param,omitempty"`
// SSL enabled protocols to use
// http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_protocols
SSLProtocols string `structs:"ssl-protocols,omitempty"`
SSLProtocols string `json:"ssl-protocols,omitempty"`
// Enables or disables the use of shared SSL cache among worker processes.
// http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_cache
SSLSessionCache bool `structs:"ssl-session-cache,omitempty"`
SSLSessionCache bool `json:"ssl-session-cache,omitempty"`
// Size of the SSL shared cache between all worker processes.
// http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_cache
SSLSessionCacheSize string `structs:"ssl-session-cache-size,omitempty"`
SSLSessionCacheSize string `json:"ssl-session-cache-size,omitempty"`
// Enables or disables session resumption through TLS session tickets.
// http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_tickets
SSLSessionTickets bool `structs:"ssl-session-tickets,omitempty"`
SSLSessionTickets bool `json:"ssl-session-tickets,omitempty"`
// Time during which a client may reuse the session parameters stored in a cache.
// http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_timeout
SSLSessionTimeout string `structs:"ssl-session-timeout,omitempty"`
SSLSessionTimeout string `json:"ssl-session-timeout,omitempty"`
// http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_buffer_size
// Sets the size of the buffer used for sending data.
// 4k helps NGINX to improve TLS Time To First Byte (TTTFB)
// https://www.igvita.com/2013/12/16/optimizing-nginx-tls-time-to-first-byte/
SSLBufferSize string `structs:"ssl-buffer-size,omitempty"`
SSLBufferSize string `json:"ssl-buffer-size,omitempty"`
// Enables or disables the use of the PROXY protocol to receive client connection
// (real IP address) information passed through proxy servers and load balancers
// such as HAproxy and Amazon Elastic Load Balancer (ELB).
// https://www.nginx.com/resources/admin-guide/proxy-protocol/
UseProxyProtocol bool `structs:"use-proxy-protocol,omitempty"`
UseProxyProtocol bool `json:"use-proxy-protocol,omitempty"`
// Enables or disables the use of the nginx module that compresses responses using the "gzip" method
// http://nginx.org/en/docs/http/ngx_http_gzip_module.html
UseGzip bool `structs:"use-gzip,omitempty"`
UseGzip bool `json:"use-gzip,omitempty"`
// Enables or disables the HTTP/2 support in secure connections
// http://nginx.org/en/docs/http/ngx_http_v2_module.html
// Default: true
UseHTTP2 bool `structs:"use-http2,omitempty"`
UseHTTP2 bool `json:"use-http2,omitempty"`
// MIME types in addition to "text/html" to compress. The special value “*” matches any MIME type.
// Responses with the “text/html” type are always compressed if UseGzip is enabled
GzipTypes string `structs:"gzip-types,omitempty"`
GzipTypes string `json:"gzip-types,omitempty"`
// Defines the number of worker processes. By default auto means number of available CPU cores
// http://nginx.org/en/docs/ngx_core_module.html#worker_processes
WorkerProcesses int `structs:"worker-processes,omitempty"`
WorkerProcesses int `json:"worker-processes,omitempty"`
}
// NewDefault returns the default nginx configuration

View file

@ -21,17 +21,11 @@ import (
"strings"
"github.com/golang/glog"
"github.com/imdario/mergo"
"github.com/fatih/structs"
"github.com/mitchellh/mapstructure"
go_camelcase "github.com/segmentio/go-camelcase"
"k8s.io/kubernetes/pkg/api"
"k8s.io/ingress/controllers/nginx/pkg/config"
"k8s.io/ingress/core/pkg/ingress/defaults"
"k8s.io/ingress/core/pkg/net/dns"
)
const (
@ -40,11 +34,6 @@ const (
whitelistSourceRange = "whitelist-source-range"
)
// StandarizeKeyNames ...
func StandarizeKeyNames(data interface{}) map[string]interface{} {
return fixKeyNames(structs.Map(data))
}
// ReadConfig obtains the configuration defined by the user merged with the defaults.
func ReadConfig(conf *api.ConfigMap) config.Configuration {
if len(conf.Data) == 0 {
@ -75,36 +64,27 @@ func ReadConfig(conf *api.ConfigMap) config.Configuration {
whitelist = append(whitelist, strings.Split(val, ",")...)
}
to := config.Configuration{}
to.Backend = defaults.Backend{
CustomHTTPErrors: filterErrors(errors),
SkipAccessLogURLs: skipUrls,
WhitelistSourceRange: whitelist,
to := config.NewDefault()
to.CustomHTTPErrors = filterErrors(errors)
to.SkipAccessLogURLs = skipUrls
to.WhitelistSourceRange = whitelist
config := &mapstructure.DecoderConfig{
Metadata: nil,
WeaklyTypedInput: true,
Result: &to,
TagName: "json",
}
def := config.NewDefault()
if err := mergo.Merge(&to, def); err != nil {
decoder, err := mapstructure.NewDecoder(config)
if err != nil {
glog.Warningf("unexpected error merging defaults: %v", err)
}
metadata := &mapstructure.Metadata{}
decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
TagName: "structs",
Result: &to,
WeaklyTypedInput: true,
Metadata: metadata,
})
err = decoder.Decode(conf.Data)
if err != nil {
glog.Infof("%v", err)
glog.Warningf("unexpected error merging defaults: %v", err)
}
nss, err := dns.GetSystemNameServers()
if err != nil {
glog.Infof("unexpected error reading /etc/resolv.conf file: %v", err)
}
to.Resolver = nss
return to
}
@ -120,11 +100,3 @@ func filterErrors(codes []int) []int {
return fa
}
func fixKeyNames(data map[string]interface{}) map[string]interface{} {
fixed := make(map[string]interface{})
for k, v := range data {
fixed[go_camelcase.Camelcase(k)] = v
}
return fixed
}

View file

@ -17,14 +17,13 @@ limitations under the License.
package template
import (
"reflect"
"testing"
"k8s.io/ingress/controllers/nginx/pkg/config"
"k8s.io/kubernetes/pkg/api"
)
func TestStandarizeKeyNames(t *testing.T) {
}
func TestFilterErrors(t *testing.T) {
e := filterErrors([]int{200, 300, 345, 500, 555, 999})
if len(e) != 4 {
@ -32,52 +31,30 @@ func TestFilterErrors(t *testing.T) {
}
}
func TestFixKeyNames(t *testing.T) {
d := map[string]interface{}{
"one": "one",
"one-example": "oneExample",
"aMore-complex_example": "aMoreComplexExample",
"a": "a",
}
fixed := fixKeyNames(d)
for k, v := range fixed {
if k != v {
t.Errorf("expected %v but retuned %v", v, k)
}
}
}
type testStruct struct {
ProxyReadTimeout int `structs:"proxy-read-timeout,omitempty"`
ProxySendTimeout int `structs:"proxy-send-timeout,omitempty"`
CustomHTTPErrors []int `structs:"custom-http-errors"`
SkipAccessLogURLs []string `structs:"skip-access-log-urls,-"`
NoTag string
}
var decodedData = &testStruct{
1,
2,
[]int{300, 400},
[]string{"/log"},
"",
}
func TestMergeConfigMapToStruct(t *testing.T) {
/*conf := &api.ConfigMap{
conf := &api.ConfigMap{
Data: map[string]string{
"custom-http-errors": "300,400",
"proxy-read-timeout": "1",
"proxy-send-timeout": "2",
"skip-access-log-urls": "/log",
"custom-http-errors": "300,400",
"proxy-read-timeout": "1",
"proxy-send-timeout": "2",
"skip-access-log-urls": "/log,/demo,/test",
"use-proxy-protocol": "true",
"use-gzip": "true",
"enable-dynamic-tls-records": "false",
"gzip-types": "text/html",
},
}*/
}
def := config.NewDefault()
def.CustomHTTPErrors = []int{300, 400}
def.SkipAccessLogURLs = []string{"/log"}
//to := ReadConfig(conf)
//if !reflect.DeepEqual(def, to) {
// t.Errorf("expected %v but retuned %v", def, to)
//}
def.SkipAccessLogURLs = []string{"/log", "/demo", "/test"}
def.ProxyReadTimeout = 1
def.ProxySendTimeout = 2
def.EnableDynamicTLSRecords = false
def.UseProxyProtocol = true
def.GzipTypes = "text/html"
to := ReadConfig(conf)
if !reflect.DeepEqual(def, to) {
t.Errorf("expected %v but retuned %v", def, to)
}
}

View file

@ -10,27 +10,27 @@ type Backend struct {
// http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_intercept_errors
// http://nginx.org/en/docs/http/ngx_http_core_module.html#error_page
// By default this is disabled
CustomHTTPErrors []int `structs:"custom-http-errors,-"`
CustomHTTPErrors []int `json:"custom-http-errors,-"`
// Defines a timeout for establishing a connection with a proxied server.
// It should be noted that this timeout cannot usually exceed 75 seconds.
// http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_connect_timeout
ProxyConnectTimeout int `structs:"proxy-connect-timeout"`
ProxyConnectTimeout int `json:"proxy-connect-timeout"`
// Timeout in seconds for reading a response from the proxied server. The timeout is set only between
// two successive read operations, not for the transmission of the whole response
// http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_read_timeout
ProxyReadTimeout int `structs:"proxy-read-timeout"`
ProxyReadTimeout int `json:"proxy-read-timeout"`
// Timeout in seconds for transmitting a request to the proxied server. The timeout is set only between
// two successive write operations, not for the transmission of the whole request.
// http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_send_timeout
ProxySendTimeout int `structs:"proxy-send-timeout"`
ProxySendTimeout int `json:"proxy-send-timeout"`
// Sets the size of the buffer used for reading the first part of the response received from the
// proxied server. This part usually contains a small response header.
// http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size)
ProxyBufferSize string `structs:"proxy-buffer-size"`
ProxyBufferSize string `json:"proxy-buffer-size"`
// Name server/s used to resolve names of upstream servers into IP addresses.
// The file /etc/resolv.conf is used as DNS resolution configuration.
@ -39,24 +39,24 @@ type Backend struct {
// SkipAccessLogURLs sets a list of URLs that should not appear in the NGINX access log
// This is useful with urls like `/health` or `health-check` that make "complex" reading the logs
// By default this list is empty
SkipAccessLogURLs []string `structs:"skip-access-log-urls,-"`
SkipAccessLogURLs []string `json:"skip-access-log-urls,-"`
// Enables or disables the redirect (301) to the HTTPS port
SSLRedirect bool `structs:"ssl-redirect"`
SSLRedirect bool `json:"ssl-redirect"`
// Number of unsuccessful attempts to communicate with the server that should happen in the
// duration set by the fail_timeout parameter to consider the server unavailable
// http://nginx.org/en/docs/http/ngx_http_upstream_module.html#upstream
// Default: 0, ie use platform liveness probe
UpstreamMaxFails int `structs:"upstream-max-fails"`
UpstreamMaxFails int `json:"upstream-max-fails"`
// Time during which the specified number of unsuccessful attempts to communicate with
// the server should happen to consider the server unavailable
// http://nginx.org/en/docs/http/ngx_http_upstream_module.html#upstream
// Default: 0, ie use platform liveness probe
UpstreamFailTimeout int `structs:"upstream-fail-timeout"`
UpstreamFailTimeout int `json:"upstream-fail-timeout"`
// WhitelistSourceRange allows limiting access to certain client addresses
// http://nginx.org/en/docs/http/ngx_http_access_module.html
WhitelistSourceRange []string `structs:"whitelist-source-range,-"`
WhitelistSourceRange []string `json:"whitelist-source-range,-"`
}