diff --git a/docs/user-guide/nginx-configuration/annotations.md b/docs/user-guide/nginx-configuration/annotations.md index 3a7b55dd5..b8f1c4a10 100644 --- a/docs/user-guide/nginx-configuration/annotations.md +++ b/docs/user-guide/nginx-configuration/annotations.md @@ -47,6 +47,7 @@ You can add these Kubernetes annotations to specific Ingress objects to customiz |[nginx.ingress.kubernetes.io/permanent-redirect-code](#permanent-redirect-code)|number| |[nginx.ingress.kubernetes.io/proxy-body-size](#custom-max-body-size)|string| |[nginx.ingress.kubernetes.io/proxy-cookie-domain](#proxy-cookie-domain)|string| +|[nginx.ingress.kubernetes.io/proxy-cookie-path](#proxy-cookie-path)|string| |[nginx.ingress.kubernetes.io/proxy-connect-timeout](#custom-timeouts)|number| |[nginx.ingress.kubernetes.io/proxy-send-timeout](#custom-timeouts)|number| |[nginx.ingress.kubernetes.io/proxy-read-timeout](#custom-timeouts)|number| @@ -489,6 +490,12 @@ Sets a text that [should be changed in the domain attribute](http://nginx.org/en To configure this setting globally for all Ingress rules, the `proxy-cookie-domain` value may be set in the [NGINX ConfigMap][configmap]. +### Proxy cookie path + +Sets a text that [should be changed in the path attribute](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cookie_path) of the "Set-Cookie" header fields of a proxied server response. + +To configure this setting globally for all Ingress rules, the `proxy-cookie-path` value may be set in the [NGINX ConfigMap][configmap]. + ### Proxy buffering Enable or disable proxy buffering [`proxy_buffering`](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffering). diff --git a/rootfs/etc/nginx/template/nginx.tmpl b/rootfs/etc/nginx/template/nginx.tmpl index bac17d2a7..39b8b130b 100644 --- a/rootfs/etc/nginx/template/nginx.tmpl +++ b/rootfs/etc/nginx/template/nginx.tmpl @@ -648,7 +648,6 @@ http { access_log off; stub_status on; } - {{ if $all.DynamicConfigurationEnabled }} location /configuration { access_log off; @@ -663,7 +662,7 @@ http { deny all; # this should be equals to configuration_data dict - client_max_body_size "10m"; + client_max_body_size 10m; proxy_buffering off; content_by_lua_block { @@ -671,7 +670,6 @@ http { } } {{ end }} - location / { {{ if .CustomErrors }} proxy_set_header X-Code 404; @@ -938,15 +936,15 @@ stream { proxy_set_header X-Auth-Request-Redirect $request_uri; {{ end }} - proxy_buffering "{{ $location.Proxy.ProxyBuffering }}"; - proxy_buffer_size "{{ $location.Proxy.BufferSize }}"; - proxy_buffers 4 "{{ $location.Proxy.BufferSize }}"; - proxy_request_buffering "{{ $location.Proxy.RequestBuffering }}"; + proxy_buffering {{ $location.Proxy.ProxyBuffering }}; + proxy_buffer_size {{ $location.Proxy.BufferSize }}; + proxy_buffers 4 {{ $location.Proxy.BufferSize }}; + proxy_request_buffering {{ $location.Proxy.RequestBuffering }}; proxy_http_version 1.1; proxy_ssl_server_name on; proxy_pass_request_headers on; - client_max_body_size "{{ $location.Proxy.BodySize }}"; + client_max_body_size {{ $location.Proxy.BodySize }}; {{ if isValidClientBodyBufferSize $location.ClientBodyBufferSize }} client_body_buffer_size {{ $location.ClientBodyBufferSize }}; {{ end }} @@ -1136,7 +1134,7 @@ stream { } {{ end }} - client_max_body_size "{{ $location.Proxy.BodySize }}"; + client_max_body_size {{ $location.Proxy.BodySize }}; {{ if isValidClientBodyBufferSize $location.ClientBodyBufferSize }} client_body_buffer_size {{ $location.ClientBodyBufferSize }}; {{ end }} @@ -1197,10 +1195,10 @@ stream { proxy_send_timeout {{ $location.Proxy.SendTimeout }}s; proxy_read_timeout {{ $location.Proxy.ReadTimeout }}s; - proxy_buffering "{{ $location.Proxy.ProxyBuffering }}"; - proxy_buffer_size "{{ $location.Proxy.BufferSize }}"; - proxy_buffers 4 "{{ $location.Proxy.BufferSize }}"; - proxy_request_buffering "{{ $location.Proxy.RequestBuffering }}"; + proxy_buffering {{ $location.Proxy.ProxyBuffering }}; + proxy_buffer_size {{ $location.Proxy.BufferSize }}; + proxy_buffers 4 {{ $location.Proxy.BufferSize }}; + proxy_request_buffering {{ $location.Proxy.RequestBuffering }}; proxy_http_version 1.1; diff --git a/test/e2e/annotations/proxy.go b/test/e2e/annotations/proxy.go index 2b1dd49f5..da63426bc 100644 --- a/test/e2e/annotations/proxy.go +++ b/test/e2e/annotations/proxy.go @@ -19,8 +19,9 @@ package annotations import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + "strings" - v1beta1 "k8s.io/api/extensions/v1beta1" + "k8s.io/api/extensions/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" @@ -40,37 +41,12 @@ var _ = framework.IngressNginxDescribe("Annotations - Proxy", func() { It("should set proxy_redirect to off", func() { host := "proxy.foo.com" + annotations := map[string]string{ + "nginx.ingress.kubernetes.io/proxy-redirect-from": "off", + "nginx.ingress.kubernetes.io/proxy-redirect-to": "goodbye.com", + } - ing, err := f.EnsureIngress(&v1beta1.Ingress{ - ObjectMeta: metav1.ObjectMeta{ - Name: host, - Namespace: f.IngressController.Namespace, - Annotations: map[string]string{ - "nginx.ingress.kubernetes.io/proxy-redirect-from": "off", - "nginx.ingress.kubernetes.io/proxy-redirect-to": "goodbye.com", - }, - }, - Spec: v1beta1.IngressSpec{ - Rules: []v1beta1.IngressRule{ - { - Host: host, - IngressRuleValue: v1beta1.IngressRuleValue{ - HTTP: &v1beta1.HTTPIngressRuleValue{ - Paths: []v1beta1.HTTPIngressPath{ - { - Path: "/", - Backend: v1beta1.IngressBackend{ - ServiceName: "http-svc", - ServicePort: intstr.FromInt(80), - }, - }, - }, - }, - }, - }, - }, - }, - }) + ing, err := ensureIngress(f, host, annotations) Expect(err).NotTo(HaveOccurred()) Expect(ing).NotTo(BeNil()) @@ -83,37 +59,12 @@ var _ = framework.IngressNginxDescribe("Annotations - Proxy", func() { It("should set proxy_redirect to default", func() { host := "proxy.foo.com" + annotations := map[string]string{ + "nginx.ingress.kubernetes.io/proxy-redirect-from": "default", + "nginx.ingress.kubernetes.io/proxy-redirect-to": "goodbye.com", + } - ing, err := f.EnsureIngress(&v1beta1.Ingress{ - ObjectMeta: metav1.ObjectMeta{ - Name: host, - Namespace: f.IngressController.Namespace, - Annotations: map[string]string{ - "nginx.ingress.kubernetes.io/proxy-redirect-from": "default", - "nginx.ingress.kubernetes.io/proxy-redirect-to": "goodbye.com", - }, - }, - Spec: v1beta1.IngressSpec{ - Rules: []v1beta1.IngressRule{ - { - Host: host, - IngressRuleValue: v1beta1.IngressRuleValue{ - HTTP: &v1beta1.HTTPIngressRuleValue{ - Paths: []v1beta1.HTTPIngressPath{ - { - Path: "/", - Backend: v1beta1.IngressBackend{ - ServiceName: "http-svc", - ServicePort: intstr.FromInt(80), - }, - }, - }, - }, - }, - }, - }, - }, - }) + ing, err := ensureIngress(f, host, annotations) Expect(err).NotTo(HaveOccurred()) Expect(ing).NotTo(BeNil()) @@ -126,37 +77,12 @@ var _ = framework.IngressNginxDescribe("Annotations - Proxy", func() { It("should set proxy_redirect to hello.com goodbye.com", func() { host := "proxy.foo.com" + annotations := map[string]string{ + "nginx.ingress.kubernetes.io/proxy-redirect-from": "hello.com", + "nginx.ingress.kubernetes.io/proxy-redirect-to": "goodbye.com", + } - ing, err := f.EnsureIngress(&v1beta1.Ingress{ - ObjectMeta: metav1.ObjectMeta{ - Name: host, - Namespace: f.IngressController.Namespace, - Annotations: map[string]string{ - "nginx.ingress.kubernetes.io/proxy-redirect-from": "hello.com", - "nginx.ingress.kubernetes.io/proxy-redirect-to": "goodbye.com", - }, - }, - Spec: v1beta1.IngressSpec{ - Rules: []v1beta1.IngressRule{ - { - Host: host, - IngressRuleValue: v1beta1.IngressRuleValue{ - HTTP: &v1beta1.HTTPIngressRuleValue{ - Paths: []v1beta1.HTTPIngressPath{ - { - Path: "/", - Backend: v1beta1.IngressBackend{ - ServiceName: "http-svc", - ServicePort: intstr.FromInt(80), - }, - }, - }, - }, - }, - }, - }, - }, - }) + ing, err := ensureIngress(f, host, annotations) Expect(err).NotTo(HaveOccurred()) Expect(ing).NotTo(BeNil()) @@ -166,4 +92,180 @@ var _ = framework.IngressNginxDescribe("Annotations - Proxy", func() { }) Expect(err).NotTo(HaveOccurred()) }) + + It("should set proxy client-max-body-size to 8m", func() { + host := "proxy.foo.com" + annotations := map[string]string{ + "nginx.ingress.kubernetes.io/proxy-body-size": "8m", + } + + ing, err := ensureIngress(f, host, annotations) + Expect(err).NotTo(HaveOccurred()) + Expect(ing).NotTo(BeNil()) + + err = f.WaitForNginxServer(host, + func(server string) bool { + return Expect(server).Should(ContainSubstring("client_max_body_size 8m;")) + }) + Expect(err).NotTo(HaveOccurred()) + }) + + It("should not set proxy client-max-body-size to incorrect value", func() { + host := "proxy.foo.com" + annotations := map[string]string{ + "nginx.ingress.kubernetes.io/proxy-body-size": "15r", + } + + ing, err := ensureIngress(f, host, annotations) + Expect(err).NotTo(HaveOccurred()) + Expect(ing).NotTo(BeNil()) + + err = f.WaitForNginxServer(host, + func(server string) bool { + return Expect(server).ShouldNot(ContainSubstring("client_max_body_size 15r;")) + }) + Expect(err).NotTo(HaveOccurred()) + }) + + It("should set valid proxy timeouts", func() { + host := "proxy.foo.com" + annotations := map[string]string{ + "nginx.ingress.kubernetes.io/proxy-connect-timeout": "50", + "nginx.ingress.kubernetes.io/proxy-send-timeout": "20", + "nginx.ingress.kubernetes.io/proxy-read-timeout": "20", + } + + ing, err := ensureIngress(f, host, annotations) + Expect(err).NotTo(HaveOccurred()) + Expect(ing).NotTo(BeNil()) + + err = f.WaitForNginxServer(host, + func(server string) bool { + return strings.Contains(server, "proxy_connect_timeout 50s;") && strings.Contains(server, "proxy_send_timeout 20s;") && strings.Contains(server, "proxy_read_timeout 20s;") + }) + Expect(err).NotTo(HaveOccurred()) + }) + + It("should not set invalid proxy timeouts", func() { + host := "proxy.foo.com" + annotations := map[string]string{ + "nginx.ingress.kubernetes.io/proxy-connect-timeout": "50k", + "nginx.ingress.kubernetes.io/proxy-send-timeout": "20k", + "nginx.ingress.kubernetes.io/proxy-read-timeout": "20k", + } + + ing, err := ensureIngress(f, host, annotations) + Expect(err).NotTo(HaveOccurred()) + Expect(ing).NotTo(BeNil()) + + err = f.WaitForNginxServer(host, + func(server string) bool { + return !strings.Contains(server, "proxy_connect_timeout 50ks;") && !strings.Contains(server, "proxy_send_timeout 20ks;") && !strings.Contains(server, "proxy_read_timeout 60s;") + }) + Expect(err).NotTo(HaveOccurred()) + }) + + It("should turn on proxy-buffering", func() { + host := "proxy.foo.com" + annotations := map[string]string{ + "nginx.ingress.kubernetes.io/proxy-buffering": "on", + "nginx.ingress.kubernetes.io/proxy-buffer-size": "8k", + } + + ing, err := ensureIngress(f, host, annotations) + Expect(err).NotTo(HaveOccurred()) + Expect(ing).NotTo(BeNil()) + + err = f.WaitForNginxServer(host, + func(server string) bool { + return strings.Contains(server, "proxy_buffering on;") && strings.Contains(server, "proxy_buffer_size 8k;") && strings.Contains(server, "proxy_buffers 4 8k;") && strings.Contains(server, "proxy_request_buffering on;") + }) + Expect(err).NotTo(HaveOccurred()) + }) + + It("should turn off proxy-request-buffering", func() { + host := "proxy.foo.com" + annotations := map[string]string{ + "nginx.ingress.kubernetes.io/proxy-request-buffering": "off", + } + + ing, err := ensureIngress(f, host, annotations) + Expect(err).NotTo(HaveOccurred()) + Expect(ing).NotTo(BeNil()) + + err = f.WaitForNginxServer(host, + func(server string) bool { + return Expect(server).Should(ContainSubstring("proxy_request_buffering off;")) + }) + Expect(err).NotTo(HaveOccurred()) + }) + + It("should build proxy next upstream", func() { + host := "proxy.foo.com" + annotations := map[string]string{ + "nginx.ingress.kubernetes.io/proxy-next-upstream": "error timeout http_502", + "nginx.ingress.kubernetes.io/proxy-next-upstream-tries": "5", + } + + ing, err := ensureIngress(f, host, annotations) + Expect(err).NotTo(HaveOccurred()) + Expect(ing).NotTo(BeNil()) + + err = f.WaitForNginxServer(host, + func(server string) bool { + return strings.Contains(server, "proxy_next_upstream error timeout http_502;") && strings.Contains(server, "proxy_next_upstream_tries 5;") + }) + Expect(err).NotTo(HaveOccurred()) + }) + + It("should setup proxy cookies", func() { + host := "proxy.foo.com" + annotations := map[string]string{ + "nginx.ingress.kubernetes.io/proxy-cookie-domain": "localhost example.org", + "nginx.ingress.kubernetes.io/proxy-cookie-path": "/one/ /", + } + + ing, err := ensureIngress(f, host, annotations) + Expect(err).NotTo(HaveOccurred()) + Expect(ing).NotTo(BeNil()) + + err = f.WaitForNginxServer(host, + func(server string) bool { + return strings.Contains(server, "proxy_cookie_domain localhost example.org;") && strings.Contains(server, "proxy_cookie_path /one/ /;") + }) + Expect(err).NotTo(HaveOccurred()) + }) + }) + +func ensureIngress(f *framework.Framework, host string, annotations map[string]string) (*v1beta1.Ingress, error) { + ing, err := f.EnsureIngress(&v1beta1.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + Name: host, + Namespace: f.IngressController.Namespace, + Annotations: annotations, + }, + Spec: v1beta1.IngressSpec{ + Rules: []v1beta1.IngressRule{ + { + Host: host, + IngressRuleValue: v1beta1.IngressRuleValue{ + HTTP: &v1beta1.HTTPIngressRuleValue{ + Paths: []v1beta1.HTTPIngressPath{ + { + Path: "/", + Backend: v1beta1.IngressBackend{ + ServiceName: "http-svc", + ServicePort: intstr.FromInt(80), + }, + }, + }, + }, + }, + }, + }, + }, + }) + + return ing, err +}