From 0f07afa01596114acdb415b236c9a2923c3a3691 Mon Sep 17 00:00:00 2001 From: Gerard Wilkinson Date: Tue, 5 Apr 2022 15:30:27 +0100 Subject: [PATCH 1/6] Add override for proxy intercept errors --- internal/ingress/defaults/main.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/internal/ingress/defaults/main.go b/internal/ingress/defaults/main.go index bc97342574..23b8018336 100644 --- a/internal/ingress/defaults/main.go +++ b/internal/ingress/defaults/main.go @@ -30,6 +30,11 @@ type Backend struct { // http://nginx.org/en/docs/http/ngx_http_core_module.html#error_page // By default this is disabled CustomHTTPErrors []int `json:"custom-http-errors"` + + // for use when using CustomHTTPErrors without intecepting service errors + // e.g. custom 404 and 503 when service-a does not exist or is not available + // but service-a can return 404 and 503 error codes without intercept + SetProxyInterceptErrors bool `json:"set-proxy-intercept-errors"` // toggles whether or not to remove trailing slashes during TLS redirects PreserveTrailingSlash bool `json:"preserve-trailing-slash"` From 67589fa644d789a15f0771f2acc29247c6a56f9c Mon Sep 17 00:00:00 2001 From: Gerard Wilkinson Date: Tue, 5 Apr 2022 15:42:20 +0100 Subject: [PATCH 2/6] Add override for proxy intercept errors --- internal/ingress/annotations/annotations.go | 83 +++++++++++---------- 1 file changed, 42 insertions(+), 41 deletions(-) diff --git a/internal/ingress/annotations/annotations.go b/internal/ingress/annotations/annotations.go index fe7400ac76..8dc53b77fa 100644 --- a/internal/ingress/annotations/annotations.go +++ b/internal/ingress/annotations/annotations.go @@ -75,48 +75,49 @@ const DeniedKeyName = "Denied" // Ingress defines the valid annotations present in one NGINX Ingress rule type Ingress struct { metav1.ObjectMeta - BackendProtocol string - Aliases []string - BasicDigestAuth auth.Config - Canary canary.Config - CertificateAuth authtls.Config - ClientBodyBufferSize string - ConfigurationSnippet string - Connection connection.Config - CorsConfig cors.Config - CustomHTTPErrors []int - DefaultBackend *apiv1.Service + BackendProtocol string + Aliases []string + BasicDigestAuth auth.Config + Canary canary.Config + CertificateAuth authtls.Config + ClientBodyBufferSize string + ConfigurationSnippet string + Connection connection.Config + CorsConfig cors.Config + CustomHTTPErrors []int + SetProxyInterceptErrors bool + DefaultBackend *apiv1.Service //TODO: Change this back into an error when https://github.com/imdario/mergo/issues/100 is resolved - FastCGI fastcgi.Config - Denied *string - ExternalAuth authreq.Config - EnableGlobalAuth bool - HTTP2PushPreload bool - Opentracing opentracing.Config - Proxy proxy.Config - ProxySSL proxyssl.Config - RateLimit ratelimit.Config - GlobalRateLimit globalratelimit.Config - Redirect redirect.Config - Rewrite rewrite.Config - Satisfy string - SecureUpstream secureupstream.Config - ServerSnippet string - ServiceUpstream bool - SessionAffinity sessionaffinity.Config - SSLPassthrough bool - UsePortInRedirects bool - UpstreamHashBy upstreamhashby.Config - LoadBalancing string - UpstreamVhost string - Whitelist ipwhitelist.SourceRange - XForwardedPrefix string - SSLCipher sslcipher.Config - Logs log.Config - InfluxDB influxdb.Config - ModSecurity modsecurity.Config - Mirror mirror.Config - StreamSnippet string + FastCGI fastcgi.Config + Denied *string + ExternalAuth authreq.Config + EnableGlobalAuth bool + HTTP2PushPreload bool + Opentracing opentracing.Config + Proxy proxy.Config + ProxySSL proxyssl.Config + RateLimit ratelimit.Config + GlobalRateLimit globalratelimit.Config + Redirect redirect.Config + Rewrite rewrite.Config + Satisfy string + SecureUpstream secureupstream.Config + ServerSnippet string + ServiceUpstream bool + SessionAffinity sessionaffinity.Config + SSLPassthrough bool + UsePortInRedirects bool + UpstreamHashBy upstreamhashby.Config + LoadBalancing string + UpstreamVhost string + Whitelist ipwhitelist.SourceRange + XForwardedPrefix string + SSLCipher sslcipher.Config + Logs log.Config + InfluxDB influxdb.Config + ModSecurity modsecurity.Config + Mirror mirror.Config + StreamSnippet string } // Extractor defines the annotation parsers to be used in the extraction of annotations From 25aadc756bafa00a6af6828930981e22fc84013d Mon Sep 17 00:00:00 2001 From: Gerard Wilkinson Date: Tue, 5 Apr 2022 15:48:39 +0100 Subject: [PATCH 3/6] Add override for proxy intercept errors --- internal/ingress/controller/config/config.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/ingress/controller/config/config.go b/internal/ingress/controller/config/config.go index f37516e78c..825a08999b 100644 --- a/internal/ingress/controller/config/config.go +++ b/internal/ingress/controller/config/config.go @@ -882,6 +882,7 @@ func NewDefault() Configuration { PreserveTrailingSlash: false, SSLRedirect: true, CustomHTTPErrors: []int{}, + SetProxyInterceptErrors: true, WhitelistSourceRange: []string{}, SkipAccessLogURLs: []string{}, LimitRate: 0, From cf80fb24a92c5637dc84858993504dd8450c1d30 Mon Sep 17 00:00:00 2001 From: Gerard Wilkinson Date: Tue, 5 Apr 2022 15:49:58 +0100 Subject: [PATCH 4/6] Add override for proxy intercept errors --- internal/ingress/types.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/internal/ingress/types.go b/internal/ingress/types.go index db4f37f990..cb0a6c201d 100644 --- a/internal/ingress/types.go +++ b/internal/ingress/types.go @@ -347,6 +347,10 @@ type Location struct { // CustomHTTPErrors specifies the error codes that should be intercepted. // +optional CustomHTTPErrors []int `json:"custom-http-errors"` + // for use when using CustomHTTPErrors without intecepting service errors + // e.g. custom 404 and 503 when service-a does not exist or is not available + // but service-a can return 404 and 503 error codes without intercept + SetProxyInterceptErrors bool `json:"set-proxy-intercept-errors"` // ModSecurity allows to enable and configure modsecurity // +optional ModSecurity modsecurity.Config `json:"modsecurity"` From 2c8744c6426e953cce1d4e57e18c54402e5de8ac Mon Sep 17 00:00:00 2001 From: Gerard Wilkinson Date: Tue, 5 Apr 2022 16:06:00 +0100 Subject: [PATCH 5/6] Add override for proxy intercept errors --- internal/ingress/annotations/annotations.go | 60 ++++++++--------- .../setproxyintercepterrors/main.go | 46 +++++++++++++ .../setproxyintercepterrors/main_test.go | 64 +++++++++++++++++++ 3 files changed, 140 insertions(+), 30 deletions(-) create mode 100644 internal/ingress/annotations/setproxyintercepterrors/main.go create mode 100644 internal/ingress/annotations/setproxyintercepterrors/main_test.go diff --git a/internal/ingress/annotations/annotations.go b/internal/ingress/annotations/annotations.go index 8dc53b77fa..5b5c4a4ce1 100644 --- a/internal/ingress/annotations/annotations.go +++ b/internal/ingress/annotations/annotations.go @@ -88,36 +88,36 @@ type Ingress struct { SetProxyInterceptErrors bool DefaultBackend *apiv1.Service //TODO: Change this back into an error when https://github.com/imdario/mergo/issues/100 is resolved - FastCGI fastcgi.Config - Denied *string - ExternalAuth authreq.Config - EnableGlobalAuth bool - HTTP2PushPreload bool - Opentracing opentracing.Config - Proxy proxy.Config - ProxySSL proxyssl.Config - RateLimit ratelimit.Config - GlobalRateLimit globalratelimit.Config - Redirect redirect.Config - Rewrite rewrite.Config - Satisfy string - SecureUpstream secureupstream.Config - ServerSnippet string - ServiceUpstream bool - SessionAffinity sessionaffinity.Config - SSLPassthrough bool - UsePortInRedirects bool - UpstreamHashBy upstreamhashby.Config - LoadBalancing string - UpstreamVhost string - Whitelist ipwhitelist.SourceRange - XForwardedPrefix string - SSLCipher sslcipher.Config - Logs log.Config - InfluxDB influxdb.Config - ModSecurity modsecurity.Config - Mirror mirror.Config - StreamSnippet string + FastCGI fastcgi.Config + Denied *string + ExternalAuth authreq.Config + EnableGlobalAuth bool + HTTP2PushPreload bool + Opentracing opentracing.Config + Proxy proxy.Config + ProxySSL proxyssl.Config + RateLimit ratelimit.Config + GlobalRateLimit globalratelimit.Config + Redirect redirect.Config + Rewrite rewrite.Config + Satisfy string + SecureUpstream secureupstream.Config + ServerSnippet string + ServiceUpstream bool + SessionAffinity sessionaffinity.Config + SSLPassthrough bool + UsePortInRedirects bool + UpstreamHashBy upstreamhashby.Config + LoadBalancing string + UpstreamVhost string + Whitelist ipwhitelist.SourceRange + XForwardedPrefix string + SSLCipher sslcipher.Config + Logs log.Config + InfluxDB influxdb.Config + ModSecurity modsecurity.Config + Mirror mirror.Config + StreamSnippet string } // Extractor defines the annotation parsers to be used in the extraction of annotations diff --git a/internal/ingress/annotations/setproxyintercepterrors/main.go b/internal/ingress/annotations/setproxyintercepterrors/main.go new file mode 100644 index 0000000000..6723433419 --- /dev/null +++ b/internal/ingress/annotations/setproxyintercepterrors/main.go @@ -0,0 +1,46 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package setproxyintercepterrors + +import ( + networking "k8s.io/api/networking/v1" + + "k8s.io/ingress-nginx/internal/ingress/annotations/parser" + "k8s.io/ingress-nginx/internal/ingress/errors" + "k8s.io/ingress-nginx/internal/ingress/resolver" +) + +type setProxyInterceptErrors struct { + r resolver.Resolver +} + +// NewParser creates a new setproxyintercepterrors annotation parser +func NewParser(r resolver.Resolver) parser.IngressAnnotation { + return serviceUpstream{r} +} + +func (s setProxyInterceptErrors) Parse(ing *networking.Ingress) (interface{}, error) { + defBackend := s.r.GetDefaultBackend() + + val, err := parser.GetBoolAnnotation("set-proxy-intercept-errors", ing) + // A missing annotation is not a problem, just use the default + if err == errors.ErrMissingAnnotations { + return defBackend.ServiceUpstream, nil + } + + return val, nil +} diff --git a/internal/ingress/annotations/setproxyintercepterrors/main_test.go b/internal/ingress/annotations/setproxyintercepterrors/main_test.go new file mode 100644 index 0000000000..89e5aa4bd6 --- /dev/null +++ b/internal/ingress/annotations/setproxyintercepterrors/main_test.go @@ -0,0 +1,64 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package serviceupstream + +import ( + "testing" + + api "k8s.io/api/core/v1" + networking "k8s.io/api/networking/v1" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/ingress-nginx/internal/ingress/annotations/parser" + "k8s.io/ingress-nginx/internal/ingress/resolver" +) + +func buildIngress() *networking.Ingress { + return &networking.Ingress{ + ObjectMeta: meta_v1.ObjectMeta{ + Name: "foo", + Namespace: api.NamespaceDefault, + }, + Spec: networking.IngressSpec{ + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, + }, + }, + } +} + +func TestParseAnnotations(t *testing.T) { + ing := buildIngress() + + _, err := NewParser(&resolver.Mock{}).Parse(ing) + if err == nil { + t.Errorf("unexpected error: %v", err) + } + + data := map[string]string{} + data[parser.GetAnnotationWithPrefix("set-proxy-intercept-errors")] = "true" + ing.SetAnnotations(data) + // test ingress using the annotation without a TLS section + _, err = NewParser(&resolver.Mock{}).Parse(ing) + if err != nil { + t.Errorf("unexpected error parsing ingress with set proxy intercept errors") + } +} From 13375dc1623362da545dac42b5760d1676f45387 Mon Sep 17 00:00:00 2001 From: Gerard Wilkinson Date: Tue, 5 Apr 2022 16:40:13 +0100 Subject: [PATCH 6/6] Add override for proxy intercept errors --- internal/ingress/annotations/annotations.go | 164 +++++++++--------- .../setproxyintercepterrors/main.go | 4 +- .../setproxyintercepterrors/main_test.go | 4 +- internal/ingress/controller/controller.go | 1 + internal/ingress/types_equals.go | 4 + rootfs/etc/nginx/template/nginx.tmpl | 4 +- 6 files changed, 94 insertions(+), 87 deletions(-) diff --git a/internal/ingress/annotations/annotations.go b/internal/ingress/annotations/annotations.go index 5b5c4a4ce1..c476cbeb9e 100644 --- a/internal/ingress/annotations/annotations.go +++ b/internal/ingress/annotations/annotations.go @@ -21,6 +21,7 @@ import ( "k8s.io/ingress-nginx/internal/ingress/annotations/canary" "k8s.io/ingress-nginx/internal/ingress/annotations/modsecurity" "k8s.io/ingress-nginx/internal/ingress/annotations/proxyssl" + "k8s.io/ingress-nginx/internal/ingress/annotations/setproxyintercepterrors" "k8s.io/ingress-nginx/internal/ingress/annotations/sslcipher" "k8s.io/ingress-nginx/internal/ingress/annotations/streamsnippet" "k8s.io/klog/v2" @@ -75,49 +76,49 @@ const DeniedKeyName = "Denied" // Ingress defines the valid annotations present in one NGINX Ingress rule type Ingress struct { metav1.ObjectMeta - BackendProtocol string - Aliases []string - BasicDigestAuth auth.Config - Canary canary.Config - CertificateAuth authtls.Config - ClientBodyBufferSize string - ConfigurationSnippet string - Connection connection.Config - CorsConfig cors.Config - CustomHTTPErrors []int + BackendProtocol string + Aliases []string + BasicDigestAuth auth.Config + Canary canary.Config + CertificateAuth authtls.Config + ClientBodyBufferSize string + ConfigurationSnippet string + Connection connection.Config + CorsConfig cors.Config + CustomHTTPErrors []int SetProxyInterceptErrors bool - DefaultBackend *apiv1.Service + DefaultBackend *apiv1.Service //TODO: Change this back into an error when https://github.com/imdario/mergo/issues/100 is resolved - FastCGI fastcgi.Config - Denied *string - ExternalAuth authreq.Config - EnableGlobalAuth bool - HTTP2PushPreload bool - Opentracing opentracing.Config - Proxy proxy.Config - ProxySSL proxyssl.Config - RateLimit ratelimit.Config - GlobalRateLimit globalratelimit.Config - Redirect redirect.Config - Rewrite rewrite.Config - Satisfy string - SecureUpstream secureupstream.Config - ServerSnippet string - ServiceUpstream bool - SessionAffinity sessionaffinity.Config - SSLPassthrough bool - UsePortInRedirects bool - UpstreamHashBy upstreamhashby.Config - LoadBalancing string - UpstreamVhost string - Whitelist ipwhitelist.SourceRange - XForwardedPrefix string - SSLCipher sslcipher.Config - Logs log.Config - InfluxDB influxdb.Config - ModSecurity modsecurity.Config - Mirror mirror.Config - StreamSnippet string + FastCGI fastcgi.Config + Denied *string + ExternalAuth authreq.Config + EnableGlobalAuth bool + HTTP2PushPreload bool + Opentracing opentracing.Config + Proxy proxy.Config + ProxySSL proxyssl.Config + RateLimit ratelimit.Config + GlobalRateLimit globalratelimit.Config + Redirect redirect.Config + Rewrite rewrite.Config + Satisfy string + SecureUpstream secureupstream.Config + ServerSnippet string + ServiceUpstream bool + SessionAffinity sessionaffinity.Config + SSLPassthrough bool + UsePortInRedirects bool + UpstreamHashBy upstreamhashby.Config + LoadBalancing string + UpstreamVhost string + Whitelist ipwhitelist.SourceRange + XForwardedPrefix string + SSLCipher sslcipher.Config + Logs log.Config + InfluxDB influxdb.Config + ModSecurity modsecurity.Config + Mirror mirror.Config + StreamSnippet string } // Extractor defines the annotation parsers to be used in the extraction of annotations @@ -129,46 +130,47 @@ type Extractor struct { func NewAnnotationExtractor(cfg resolver.Resolver) Extractor { return Extractor{ map[string]parser.IngressAnnotation{ - "Aliases": alias.NewParser(cfg), - "BasicDigestAuth": auth.NewParser(auth.AuthDirectory, cfg), - "Canary": canary.NewParser(cfg), - "CertificateAuth": authtls.NewParser(cfg), - "ClientBodyBufferSize": clientbodybuffersize.NewParser(cfg), - "ConfigurationSnippet": snippet.NewParser(cfg), - "Connection": connection.NewParser(cfg), - "CorsConfig": cors.NewParser(cfg), - "CustomHTTPErrors": customhttperrors.NewParser(cfg), - "DefaultBackend": defaultbackend.NewParser(cfg), - "FastCGI": fastcgi.NewParser(cfg), - "ExternalAuth": authreq.NewParser(cfg), - "EnableGlobalAuth": authreqglobal.NewParser(cfg), - "HTTP2PushPreload": http2pushpreload.NewParser(cfg), - "Opentracing": opentracing.NewParser(cfg), - "Proxy": proxy.NewParser(cfg), - "ProxySSL": proxyssl.NewParser(cfg), - "RateLimit": ratelimit.NewParser(cfg), - "GlobalRateLimit": globalratelimit.NewParser(cfg), - "Redirect": redirect.NewParser(cfg), - "Rewrite": rewrite.NewParser(cfg), - "Satisfy": satisfy.NewParser(cfg), - "SecureUpstream": secureupstream.NewParser(cfg), - "ServerSnippet": serversnippet.NewParser(cfg), - "ServiceUpstream": serviceupstream.NewParser(cfg), - "SessionAffinity": sessionaffinity.NewParser(cfg), - "SSLPassthrough": sslpassthrough.NewParser(cfg), - "UsePortInRedirects": portinredirect.NewParser(cfg), - "UpstreamHashBy": upstreamhashby.NewParser(cfg), - "LoadBalancing": loadbalancing.NewParser(cfg), - "UpstreamVhost": upstreamvhost.NewParser(cfg), - "Whitelist": ipwhitelist.NewParser(cfg), - "XForwardedPrefix": xforwardedprefix.NewParser(cfg), - "SSLCipher": sslcipher.NewParser(cfg), - "Logs": log.NewParser(cfg), - "InfluxDB": influxdb.NewParser(cfg), - "BackendProtocol": backendprotocol.NewParser(cfg), - "ModSecurity": modsecurity.NewParser(cfg), - "Mirror": mirror.NewParser(cfg), - "StreamSnippet": streamsnippet.NewParser(cfg), + "Aliases": alias.NewParser(cfg), + "BasicDigestAuth": auth.NewParser(auth.AuthDirectory, cfg), + "Canary": canary.NewParser(cfg), + "CertificateAuth": authtls.NewParser(cfg), + "ClientBodyBufferSize": clientbodybuffersize.NewParser(cfg), + "ConfigurationSnippet": snippet.NewParser(cfg), + "Connection": connection.NewParser(cfg), + "CorsConfig": cors.NewParser(cfg), + "CustomHTTPErrors": customhttperrors.NewParser(cfg), + "SetProxyInterceptErrors": setproxyintercepterrors.NewParser(cfg), + "DefaultBackend": defaultbackend.NewParser(cfg), + "FastCGI": fastcgi.NewParser(cfg), + "ExternalAuth": authreq.NewParser(cfg), + "EnableGlobalAuth": authreqglobal.NewParser(cfg), + "HTTP2PushPreload": http2pushpreload.NewParser(cfg), + "Opentracing": opentracing.NewParser(cfg), + "Proxy": proxy.NewParser(cfg), + "ProxySSL": proxyssl.NewParser(cfg), + "RateLimit": ratelimit.NewParser(cfg), + "GlobalRateLimit": globalratelimit.NewParser(cfg), + "Redirect": redirect.NewParser(cfg), + "Rewrite": rewrite.NewParser(cfg), + "Satisfy": satisfy.NewParser(cfg), + "SecureUpstream": secureupstream.NewParser(cfg), + "ServerSnippet": serversnippet.NewParser(cfg), + "ServiceUpstream": serviceupstream.NewParser(cfg), + "SessionAffinity": sessionaffinity.NewParser(cfg), + "SSLPassthrough": sslpassthrough.NewParser(cfg), + "UsePortInRedirects": portinredirect.NewParser(cfg), + "UpstreamHashBy": upstreamhashby.NewParser(cfg), + "LoadBalancing": loadbalancing.NewParser(cfg), + "UpstreamVhost": upstreamvhost.NewParser(cfg), + "Whitelist": ipwhitelist.NewParser(cfg), + "XForwardedPrefix": xforwardedprefix.NewParser(cfg), + "SSLCipher": sslcipher.NewParser(cfg), + "Logs": log.NewParser(cfg), + "InfluxDB": influxdb.NewParser(cfg), + "BackendProtocol": backendprotocol.NewParser(cfg), + "ModSecurity": modsecurity.NewParser(cfg), + "Mirror": mirror.NewParser(cfg), + "StreamSnippet": streamsnippet.NewParser(cfg), }, } } diff --git a/internal/ingress/annotations/setproxyintercepterrors/main.go b/internal/ingress/annotations/setproxyintercepterrors/main.go index 6723433419..c583a10166 100644 --- a/internal/ingress/annotations/setproxyintercepterrors/main.go +++ b/internal/ingress/annotations/setproxyintercepterrors/main.go @@ -30,7 +30,7 @@ type setProxyInterceptErrors struct { // NewParser creates a new setproxyintercepterrors annotation parser func NewParser(r resolver.Resolver) parser.IngressAnnotation { - return serviceUpstream{r} + return setProxyInterceptErrors{r} } func (s setProxyInterceptErrors) Parse(ing *networking.Ingress) (interface{}, error) { @@ -39,7 +39,7 @@ func (s setProxyInterceptErrors) Parse(ing *networking.Ingress) (interface{}, er val, err := parser.GetBoolAnnotation("set-proxy-intercept-errors", ing) // A missing annotation is not a problem, just use the default if err == errors.ErrMissingAnnotations { - return defBackend.ServiceUpstream, nil + return defBackend.SetProxyInterceptErrors, nil } return val, nil diff --git a/internal/ingress/annotations/setproxyintercepterrors/main_test.go b/internal/ingress/annotations/setproxyintercepterrors/main_test.go index 89e5aa4bd6..6272e3a9b4 100644 --- a/internal/ingress/annotations/setproxyintercepterrors/main_test.go +++ b/internal/ingress/annotations/setproxyintercepterrors/main_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package serviceupstream +package setproxyintercepterrors import ( "testing" @@ -49,7 +49,7 @@ func TestParseAnnotations(t *testing.T) { ing := buildIngress() _, err := NewParser(&resolver.Mock{}).Parse(ing) - if err == nil { + if err != nil { t.Errorf("unexpected error: %v", err) } diff --git a/internal/ingress/controller/controller.go b/internal/ingress/controller/controller.go index 651e983a84..96ae83f6de 100644 --- a/internal/ingress/controller/controller.go +++ b/internal/ingress/controller/controller.go @@ -1407,6 +1407,7 @@ func locationApplyAnnotations(loc *ingress.Location, anns *annotations.Ingress) loc.BackendProtocol = anns.BackendProtocol loc.FastCGI = anns.FastCGI loc.CustomHTTPErrors = anns.CustomHTTPErrors + loc.SetProxyInterceptErrors = anns.SetProxyInterceptErrors loc.ModSecurity = anns.ModSecurity loc.Satisfy = anns.Satisfy loc.Mirror = anns.Mirror diff --git a/internal/ingress/types_equals.go b/internal/ingress/types_equals.go index 3e39940a33..4a0571a0cb 100644 --- a/internal/ingress/types_equals.go +++ b/internal/ingress/types_equals.go @@ -466,6 +466,10 @@ func (l1 *Location) Equal(l2 *Location) bool { return false } + if l1.SetProxyInterceptErrors != l2.SetProxyInterceptErrors { + return false + } + return true } diff --git a/rootfs/etc/nginx/template/nginx.tmpl b/rootfs/etc/nginx/template/nginx.tmpl index 2ee76831cc..57e823dd67 100755 --- a/rootfs/etc/nginx/template/nginx.tmpl +++ b/rootfs/etc/nginx/template/nginx.tmpl @@ -467,7 +467,7 @@ http { ssl_certificate {{ $cfg.DefaultSSLCertificate.PemFileName }}; ssl_certificate_key {{ $cfg.DefaultSSLCertificate.PemFileName }}; - {{ if gt (len $cfg.CustomHTTPErrors) 0 }} + {{ if and (gt (len $cfg.CustomHTTPErrors) 0) $cfg.SetProxyInterceptErrors }} proxy_intercept_errors on; {{ end }} @@ -1351,7 +1351,7 @@ stream { {{ end }} {{/* if a location-specific error override is set, add the proxy_intercept here */}} - {{ if $location.CustomHTTPErrors }} + {{ if and $location.CustomHTTPErrors $location.SetProxyInterceptErrors }} # Custom error pages per ingress proxy_intercept_errors on; {{ end }}