diff --git a/controllers/nginx/pkg/config/config.go b/controllers/nginx/pkg/config/config.go index a2ad73155..7e5eb5f26 100644 --- a/controllers/nginx/pkg/config/config.go +++ b/controllers/nginx/pkg/config/config.go @@ -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 processor’s 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 directive’s 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 diff --git a/controllers/nginx/pkg/template/configmap.go b/controllers/nginx/pkg/template/configmap.go index 83adac4bb..76d0b90f1 100644 --- a/controllers/nginx/pkg/template/configmap.go +++ b/controllers/nginx/pkg/template/configmap.go @@ -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 -} diff --git a/controllers/nginx/pkg/template/configmap_test.go b/controllers/nginx/pkg/template/configmap_test.go index e80a29917..0edbefe24 100644 --- a/controllers/nginx/pkg/template/configmap_test.go +++ b/controllers/nginx/pkg/template/configmap_test.go @@ -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) + } } diff --git a/core/pkg/ingress/defaults/main.go b/core/pkg/ingress/defaults/main.go index bd90576a6..88a817d93 100644 --- a/core/pkg/ingress/defaults/main.go +++ b/core/pkg/ingress/defaults/main.go @@ -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,-"` }